Katherine oversees editorial operations across all six brands. Before joining The Meridan Group, she spent 14 years at the Minneapolis Star Tribune, where she led the metro desk through its digital transformation. She holds a Master's in Journalism from Northwestern's Medill School.
This article describes new features in the .NET runtime for .NET 11. It was last updated for release candidate 2 (RC 2).
Updated minimum hardware requirements
The minimum hardware requirements for .NET 11 have been updated to require more modern instruction sets on both x86/x64 and Arm64 architectures. Additionally, the ReadyToRun (R2R) compilation targets have been updated to take advantage of newer hardware capabilities.
Arm64 requirements
For Apple, there's no change to the minimum hardware or the ReadyToRun target. The Apple M1 chips are approximately equivalent to
armv8.5-a
and provide support for at least the
AdvSimd
(NEON),
CRC
,
DOTPROD
,
LSE
,
RCPC
,
RCPC2
, and
RDMA
instruction sets.
For Linux, there's no change to the minimum hardware. .NET continues to support devices such as Raspberry Pi that might only provide support for the
AdvSimd
instruction set. The ReadyToRun target has been updated to include the
LSE
instruction set, which might result in additional jitting overhead if you launch an application.
For Windows, the baseline is updated to require the
LSE
instruction set. This is
required by Windows 11
and by
all Arm64 CPUs officially supported by Windows 10
. Additionally, it's inline with the Arm SBSA (Server Base System Architecture) requirements. The ReadyToRun target has been updated to be
armv8.2-a + RCPC
, which provides support for at least
AdvSimd
,
CRC
,
LSE
,
RCPC
, and
RDMA
, and covers the majority of hardware officially supported.
OS
Previous JIT/AOT minimum
New JIT/AOT minimum
Previous R2R target
New R2R target
Apple
Apple M1
(No change)
Apple M1
(No change)
Linux
armv8.0-a
(No change)
armv8.0-a
armv8.0-a + LSE
Windows
armv8.0-a
armv8.0-a + LSE
armv8.0-a
armv8.2-a + RCPC
x86/x64 requirements
For all three operating systems (Apple, Linux, and Windows), the baseline is updated from
x86-64-v1
to
x86-64-v2
. This changes the hardware from only guaranteeing
CMOV
,
CX8
,
SSE
, and
SSE2
to also guaranteeing
CX16
,
POPCNT
,
SSE3
,
SSSE3
,
SSE4.1
, and
SSE4.2
. This guarantee is required by Windows 11 and by all x86/x64 CPUs officially supported on Windows 10. It includes all chips still officially supported by Intel and AMD, with the last older chips having gone out of support around 2013.
The ReadyToRun target has been updated to
x86-64-v3
for Windows and Linux, which additionally includes the
AVX
,
AVX2
,
BMI1
,
BMI2
,
F16C
,
FMA
,
LZCNT
, and
MOVBE
instruction sets. The ReadyToRun target for Apple remains unchanged.
OS
Previous JIT/AOT minimum
New JIT/AOT minimum
Previous R2R target
New R2R target
Apple
x86-64-v1
x86-64-v2
x86-64-v2
(No change)
Linux
x86-64-v1
x86-64-v2
x86-64-v2
x86-64-v3
Windows
x86-64-v1
x86-64-v2
x86-64-v2
x86-64-v3
Impact
Starting with .NET 11, .NET fails to run on older hardware and might print a message similar to the following:
The current CPU is missing one or more of the baseline instruction sets.
For
ReadyToRun
-capable assemblies, there might be additional startup overhead on some supported hardware that doesn't meet the expected support for a typical device.
Reason for change
.NET supports a broad range of hardware, often above and beyond the minimum hardware requirements put in place by the underlying operating system. This support adds significant complexity to the codebase, particularly for much older hardware that's unlikely to still be in use. Additionally, it defines a "lowest common denominator" that AOT targets must default to, which can, in some scenarios, lead to reduced performance.
The update to the minimum baseline was made to reduce the maintenance complexity of the codebase and to better align with the documented (and often enforced) hardware requirements of the underlying operating system.
For more information, see
Minimum hardware requirements updated
.
Runtime Async
.NET 11 introduces runtime-native async (Runtime Async V2), a significant step toward replacing compiler-generated async state machines with runtime-managed suspension and resumption. Instead of the compiler emitting state-machine classes, the runtime itself tracks async execution, producing cleaner stack traces, better debuggability, and lower overhead.
Runtime Async is a preview feature. To opt in, add the following property to your project file:
runtime-async=on
A
net11.0
project no longer requires
true
to use Runtime Async.
The .NET runtime libraries themselves are compiled with
runtime-async=on
. The runtime libraries no longer contain compiler-generated state machines and rely entirely on runtime-provided async. This makes it possible to migrate an entire app (with only library dependencies) to the new model, and it provides broad functional and performance validation of the feature. The product team welcomes any reports—positive or negative—about throughput and library size changes you observe.
.NET 11 also includes two additional improvements:
Covariant
Task
→
Task
overrides:
When a derived class returns
Task
for a base method that returns
Task
, the runtime now generates a void-returning thunk that bridges the calling convention difference, so virtual dispatch works for both flavors. The same fix applies to NativeAOT.
Inlining in crossgen2:
Restrictions that prevented runtime-async methods from being inlined during ReadyToRun (R2R) compilation have been removed. All async tests pass with both crossgen2 and composite R2R, and inlining of await-less async calls (the synchronous fast path) is confirmed end-to-end.
Note
The
DOTNET_RuntimeAsync
and
UNSUPPORTED_RuntimeAsync
environment variables that previously controlled runtime-async behavior have been removed. To opt out of runtime-async per project, set
false
in your project file instead of relying on the environment variable.
Cleaner live stack traces
The most visible improvement is in
live stack traces
—what profilers, debuggers, and
new StackTrace()
see during execution. With compiler-generated async, each async method produces multiple frames from state-machine infrastructure. With Runtime Async, the actual methods appear directly on the call stack.
// To enable runtime async, add the following to your .csproj:
// runtime-async=on
await OuterAsync();
static async Task OuterAsync()
{
await Task.CompletedTask;
await MiddleAsync();
}
static async Task MiddleAsync()
{
await Task.CompletedTask;
await InnerAsync();
}
static async Task InnerAsync()
{
await Task.CompletedTask;
Console.WriteLine(new StackTrace(fNeedFileInfo: true));
}
Without
runtime-async
—13 frames, state-machine infrastructure visible:
at Program.<$>g__InnerAsync|0_2() in Program.cs:line 24
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](...)
at Program.<$>g__InnerAsync|0_2()
at Program.<$>g__MiddleAsync|0_1() in Program.cs:line 14
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](...)
at Program.<$>g__MiddleAsync|0_1()
at Program.<$>g__OuterAsync|0_0() in Program.cs:line 8
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](...)
at Program.<$>g__OuterAsync|0_0()
at Program.$(String[] args) in Program.cs:line 3
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](...)
at Program.$(String[] args)
at Program.(String[] args)
With
runtime-async
—5 frames, the real call chain:
at Program.<$>g__InnerAsync|0_2() in Program.cs:line 24
at Program.<$>g__MiddleAsync|0_1() in Program.cs:line 14
at Program.<$>g__OuterAsync|0_0() in Program.cs:line 8
at Program.$(String[] args) in Program.cs:line 3
at Program.(String[] args)
Note