Build1 publisher3 min readPublished
Native AOT beat SnapStart's .NET cold start by 44.5% over five samples each
AWS does not offer SnapStart on the Native AOT managed runtime, so this test compared two runtimes as well as two features, and that missing combination is also why the numbers map onto a real deployment choice.
The Engineer · Build desk

What happened
- Across five cold requests per configuration on the same 128 MB .NET function, Native AOT averaged 471.72 ms against SnapStart's 849.43 ms, which the author reports as 44.5% faster.
- By the author's decomposition, 81.7% of that cold-start difference came from the first handler invocation. The snapshot restore step SnapStart exists to provide accounts for the remainder.
- Warm requests produced no winner, with Native AOT holding the lower median at 35.68 ms against 39.50 ms and SnapStart the lower mean at 53.67 ms against 57.32 ms, over 8 and 12 samples.
- An illustrative pricing model at one million invocations a month with 1% cold starts puts Native AOT at $0.33 per function per month and SnapStart at $0.98, mostly from caching and restoration fees.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- constraint While AWS keeps SnapStart off the Native AOT runtime, nobody can run the controlled version of this test, so every .NET comparison of the two carries a runtime difference inside its numbers.
- decision Because the modelled gap sits in snapshot caching and restoration fees, the configuration choice turns on how often a function goes cold.
- cost At 1% cold starts the entire disputed amount is under a dollar per function per month, so cost alone will not pay for the engineering time to switch a small fleet.
- contradiction The warm batches disagree by statistic, so a team quoting only the median or only the mean can defend either configuration from the same twenty invocations.
The restore step was the smaller half. In the raw CloudWatch REPORT lines published with the dev.to writeup, SnapStart's Restore Duration was 346.09 ms and its handler execution 496.66 ms; Native AOT's Init Duration was 267.41 ms and its execution 192.15 ms [8][9]. Restore-versus-init accounts for 78.68 ms of the gap and first handler execution for 304.51 ms, 383.19 ms in total [10]. Those two invocations sum to 842.75 ms and 459.56 ms, within 3% of the five-sample cold means, and 79.5% of their gap sits in the handler call [7][2]. The five-sample batch puts that share at 81.7% [3].
The same lines show what AWS bills. AOT reported 192.15 ms of duration and 460 ms billed, because init is inside the billed number: 192.15 plus 267.41 is 459.56 [3]. SnapStart reported 496.66 ms of duration, 500 ms billed, and 3 ms of billed restore against a 346.09 ms restore [8]. The restore fee arrives on a different line, and in the author's pricing model SnapStart's caching and restoration charges account for most of the difference between $0.33 and $0.98 per function per month [5].
A million invocations a month at 1% cold starts is 10,000 cold starts and a 65 cent difference, or about 6.5 cents per thousand cold starts [4]. One function does not justify a rebuild. Three hundred functions is $195 a month [5].
SnapStart is not available on the Native AOT managed runtime, so AOT ran on Amazon Linux 2023 and SnapStart on the .NET 10 (C#/F#/PowerShell) managed runtime [6]. "Treat this as directional evidence for this workload, not a universal verdict," the author wrote [7]. The constraint is also what makes the result usable: the two cells AWS offers are the two cells a team can actually ship. The test cannot say what SnapStart alone does to a given .NET binary, since it cannot be turned on for an AOT build [6].
The headline 44.5% is 377.71 ms divided by SnapStart's 849.43 ms mean [1]. For it to transfer, your first handler execution has to behave like theirs. The author names network reconnection, downstream service latency, and first-use initialization as possible explanations for the 304.51 ms, and says the logs do not establish any of them [11]. If it is first-use initialization inside the handler, it is your code, and it moves when the code moves. The writeup calls the single-sample pair a record of what happened, with no claim on typical or p95 performance, and the batch figures small-sample measurements plus a pricing model [12][13].
The warm numbers split. AOT's median was 3.825 ms lower and SnapStart's mean 6.4% lower [14]. Both batches skew right: AOT's mean sits 21.64 ms above its median, SnapStart's 14.17 ms above [6]. With eight AOT and twelve SnapStart invocations, one slow call moves a mean [4].
What to watch
- Whether AWS enables SnapStart on the Native AOT managed runtime, which would make the controlled version of this test possible.
- A larger run reporting p95 cold latency instead of five cold samples per configuration.
- A breakdown of the 304.51 ms first-execution gap that separates downstream call latency from first-use initialization in the handler.