Introduction to Native AOT(Ahead of Time) Compilation in DotNet
AOT compilation to native code
In standard .NET development, we compile and build our code to Intermediate Language (IL). Then, when we run the application, the JIT (Just-In-Time) compiler, compiles it to native code and runs it. This is the reason for the slight delay we see when we first run an application. With the new feature in .NET 7, we can compile our code directly to the native version and hence the first run is also very fast. The process to do this is quite simple and we will look at it below. Let us create a console application using Visual Studio 2022 Community edition.
Why use native AOT with ASP.NET Core
Publishing and deploying a native AOT app provides the following benefits:
- Minimized disk footprint: When publishing using native AOT, a single executable is produced containing just the code from external dependencies that is needed to support the program. Reduced executable size can lead to:
- Smaller container images, for example in containerized deployment scenarios.
- Reduced deployment time from smaller images.
- Reduced startup time: Native AOT applications can show reduced start-up times, which means
- The app is ready to service requests quicker.
- Improved deployment where container orchestrators need to manage transition from one version of the app to another.
- Reduced memory demand: Native AOT apps can have reduced memory demands, depending on the work done by the app. Reduced memory consumption can lead to greater deployment density and improved scalability.
The template app was run in our benchmarking lab to compare performance of an AOT published app, a trimmed runtime app, and an untrimmed runtime app. The following chart shows the results of the benchmarking:
ASP.NET Core and native AOT compatibility
Not all features in ASP.NET Core are currently compatible with native AOT. The following table summarizes ASP.NET Core feature compatibility with native AOT:
For more information on limitations, see:
- Limitations of Native AOT deployment
- Introduction to AOT warnings
- Known trimming incompatibilities
- Introduction to trim warnings
- GitHub issue dotnet/core #8288
It’s important to test an app thoroughly when moving to a native AOT deployment model. The AOT deployed app should be tested to verify functionality hasn’t changed from the untrimmed and JIT-compiled app. When building the app, review and correct AOT warnings. An app that issues AOT warnings during publishing may not work correctly. If no AOT warnings are issued at publish time, the published AOT app should work the same as the untrimmed and JIT-compiled app.
Native AOT publishing
Native AOT is enabled with the PublishAot
MSBuild property. The following example shows how to enable native AOT in a project file:
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>
This setting enables native AOT compilation during publish and enables dynamic code usage analysis during build and editing. A project that uses native AOT publishing uses JIT compilation when running locally. An AOT app has the following differences from a JIT-compiled app:
- Features that aren’t compatible with native AOT are disabled and throw exceptions at run time.
- A source analyzer is enabled to highlight code that isn’t compatible with native AOT. At publish time, the entire app, including NuGet packages, are analyzed for compatibility again.
Native AOT analysis includes all of the app’s code and the libraries the app depends on. Review native AOT warnings and take corrective steps. It’s a good idea to publish apps frequently to discover issues early in the development lifecycle.
In .NET 8, native AOT is supported by the following ASP.NET Core app types:
- minimal APIs — For more information, see the The Web API (native AOT) template section later in this article.
- gRPC — For more information, see gRPC and native AOT.
- Worker services — For more information, see AOT in Worker Service templates.
The Web API (native AOT) template
The ASP.NET Core Web API (native AOT) template (short name webapiaot
) creates a project with AOT enabled. The template differs from the Web API project template in the following ways:
- Uses minimal APIs only, as MVC isn’t yet compatible with native AOT.
- Uses the CreateSlimBuilder() API to ensure only the essential features are enabled by default, minimizing the app’s deployed size.
- Is configured to listen on HTTP only, as HTTPS traffic is commonly handled by an ingress service in cloud-native deployments.
- Doesn’t include a launch profile for running under IIS or IIS Express.
- Creates an
.http
file configured with sample HTTP requests that can be sent to the app's endpoints. - Includes a sample
Todo
API instead of the weather forecast sample. - Adds
PublishAot
to the project file, as shown earlier in this article. - Enables the JSON serializer source generators. The source generator is used to generate serialization code at build time, which is required for native AOT compilation.