Can a C# developer truly run a .NET 8 Native AOT binary at the edge?
In 2024 more than 40% of latency‑sensitive traffic is served from edge platforms, and developers are scrambling for a way to ship familiar C# code without the overhead of a full runtime. .NET 8 introduced Native AOT, a compiler that produces a single, statically linked executable. When you combine that with WebAssembly (Wasm) and Cloudflare Workers, you can execute the same code within milliseconds of the user’s request, all while keeping the bundle under 5 MB.
Why edge computing benefits from Native AOT
Traditional .NET deployments rely on JIT compilation and a large shared runtime (≈150 MB). On an edge node, memory limits are often 128 MB and cold‑start times must stay under 50 ms. Native AOT eliminates the JIT, reduces binary size to 2‑4 MB, and removes the need for a separate runtime folder. The result is a deterministic start‑up that fits comfortably inside Cloudflare’s 10 MB Worker limit when compiled to Wasm.
Real‑world benchmarks from Microsoft show a 30‑40% reduction in cold‑start latency for AOT‑compiled services compared with regular .NET 6 containers. For a simple API that returns JSON, the difference is from 85 ms to 52 ms on a global edge network.
Preparing a .NET 8 Native AOT project
Start with a clean .NET 8 console template. The following commands create the project, enable AOT publishing, and add the Wasmtime runtime that Cloudflare Workers use under the hood.
dotnet new console -n EdgeApp -f net8.0
cd EdgeApp
sed -i '//a \ <PropertyGroup>\n\t\t<PublishAot>true</PublishAot>\n\t</PropertyGroup>' EdgeApp.csproj
Next, add a minimal HTTP handler. Cloudflare Workers expose a fetch event that you can bind to from Wasm.
using System.Text.Json;
public class Worker
{
public static async Task<string> HandleAsync(string requestBody)
{
var payload = new { message = "Hello from .NET 8 AOT!", timestamp = DateTime.UtcNow };
return JsonSerializer.Serialize(payload);
}
}
Notice the use of only System.* namespaces – they are the ones fully supported by Native AOT. Avoid reflection, dynamic code generation, or third‑party libraries that rely on the full runtime.
Compiling to WebAssembly with WasmEdge
Microsoft’s dotnet-wasi toolchain can target the wasm32-wasi platform. Install the preview SDK and run the publish command.
dotnet workload install wasi-experimental
dotnet publish -c Release -r wasi-wasm --self-contained false /p:PublishTrimmed=true /p:InvariantGlobalization=true
The output is a EdgeApp.wasm file roughly 3.2 MB in size. Verify it with wasm-objdump -h EdgeApp.wasm to ensure the _start entry point is present.
Deploying to Cloudflare Workers
Cloudflare provides the wrangler CLI to upload Wasm modules as Workers. First, create a wrangler.toml configuration.
name = "dotnet-aot-worker"
compatibility_date = "2024-08-01"
main = "src/index.js"
[wasm_modules]
edgeapp = "./bin/Release/net8.0/wasi-wasm/publish/EdgeApp.wasm"
Then write a tiny JavaScript shim that forwards the request to the Wasm module.
addEventListener('fetch', event => {
event.respondWith(handle(event.request))
})
async function handle(request) {
const { default: wasm } = await import('./edgeapp')
const body = await request.text()
const result = await wasm.handleAsync(body)
return new Response(result, { headers: { 'Content-Type': 'application/json' } })
}
Deploy with a single command:
wrangler publish
After a few seconds the Worker is live on a global network of over 300 data centers. A curl request to the Worker URL returns the JSON payload generated by the .NET AOT binary.
Performance tips and monitoring
1. Trim unused code. Use /p:PublishTrimmed=true and add a TrimmerRoot XML file for any reflection you must keep.
2. Enable SIMD. Add /p:EnableSIMD=true to the publish step; many numeric workloads see a 15% boost.
3. Cache cold starts. Cloudflare offers worker_threads that keep a Wasm instance warm for up to 30 seconds. Include a keep_alive flag in wrangler.toml to reduce the first‑request penalty.
4. Observe latency. Use Cloudflare’s Analytics>Workers dashboard or instrument the .NET code with System.Diagnostics.Stopwatch and emit custom metrics via workers.dev endpoints.
By following these steps, a C# team can ship a full‑stack API to the edge without rewriting in JavaScript or Rust, preserving existing libraries and developer expertise.
Conclusion
Running .NET 8 Native AOT applications on Cloudflare Workers via WebAssembly bridges the gap between enterprise C# ecosystems and ultra‑low‑latency edge delivery. The workflow—create a console app, enable AOT, compile to Wasm, and publish with Wrangler—fits into a half‑day sprint and produces binaries under 5 MB that start in under 30 ms worldwide. As edge platforms continue to dominate latency‑critical use cases, mastering this stack gives .NET developers a competitive edge without abandoning the language they love.
Sources
Microsoft .NET Documentation – Native AOT
Cloudflare Workers Documentation – Wrangler CLI
WasmEdge Official Guides
Author: Mahmut Sarıkaya — sarikayadev.com
