Updated on October 20, 2026: .NET 11 is in RC 2 (released October 13, 2026), with general availability expected in November 2026.
The .NET ecosystem keeps moving, and .NET 11 brings changes to the runtime, the language, and the tooling. Below is what actually changes in your code and your infrastructure — without numbers that the official materials do not contain.
Release Schedule and Support
.NET 11 is expected to reach general availability in November 2026 as a Standard Term Support (STS) release. STS releases get two years of support from the release date, which puts the end of support in November 2028. That is different from .NET 10 (LTS), which is supported until November 14, 2028.
Note: odd-numbered releases are STS, even-numbered ones are LTS. .NET 11 is STS, .NET 12 will be LTS. If you run .NET 10 (LTS) in production, your runway does not end in 2026 — it ends in November 2028.
Key dates
| Milestone | Date |
|---|---|
| Preview 1 | February 10, 2026 |
| Preview 2 | March 10, 2026 |
| RC 1 | September 8, 2026 |
| RC 2 | October 13, 2026 |
| GA release | expected in November 2026 |
RC 2 ships with a go-live support license, so it is usable in production. Support for RC 2 itself runs until November 10, 2026 — after that, move to the GA build.
Runtime-Native Async
One of the most significant changes is runtime-native async (Runtime Async V2). The runtime takes over tracking the state of an async method instead of the compiler generating a separate state machine class for every method.
The thing to understand before you start migrating code: this is a preview feature, and it is not enabled by default.
How to opt in
<PropertyGroup>
<TargetFramework>net11.0</TargetFramework>
<Features>runtime-async=on</Features>
</PropertyGroup>
Projects targeting net11.0 no longer need <EnablePreviewFeatures>true</EnablePreviewFeatures>. You can opt out per project with <UseRuntimeAsync>false</UseRuntimeAsync>.
The runtime libraries themselves are compiled with runtime-async=on, so the BCL no longer contains compiler-generated state machines. Your application code, however, only moves to the new model after an explicit opt-in.
What it buys you
- Cleaner stack traces — no more deeply nested
MoveNext()calls - Lower overhead — the runtime reuses continuation objects and does not save unchanged locals
- Better debugging — breakpoints bind correctly inside runtime-async methods, and the debugger steps across
awaitboundaries without jumping into compiler-generated infrastructure - NativeAOT and ReadyToRun — the model works beyond JIT-compiled code
What the model does not do: your existing async/await code does not get faster on its own. Without the opt-in it still compiles into a state machine.
Performance: what actually changed
Microsoft does not publish headline performance numbers for .NET 11 in the shape of "40% faster across the board". The verifiable changes are narrow:
- Runtime Async — JIT compilation of a dedicated runtime-async version of synchronous task-returning methods; continuations that opt out of
ExecutionContextcapture when no ambient state is in use; tail-merged suspension points that reduce generated code size - Tiered compilation — task and value-task factory intrinsics, plus implicit tailcall improvements
- MSBuild — wildcard matching during project evaluation is 10–13% faster with 16–34% fewer allocations (per Microsoft's Windows benchmarks)
Those numbers apply to the specific scenarios Microsoft measured. They do not carry over to your system: the only correct way to learn what the release does for you is to take measurements on your own workload (dotnet-counters, BenchmarkDotNet, a load test in a stand that resembles production).
C# 15
.NET 11 ships with C# 15. C# 15 is the default language version for projects that target .NET 11 — you no longer need <LangVersion>preview</LangVersion>.
Collection expression arguments
You can now pass arguments to a collection's constructor or factory method directly inside the collection expression — a with(...) element goes first:
// Before
List<string> names = new(capacity: values.Length * 2);
names.AddRange(values);
var set = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Hello", "HELLO" };
// C# 15
List<string> names = [with(capacity: values.Length * 2), .. values];
HashSet<string> set = [with(StringComparer.OrdinalIgnoreCase), "Hello", "HELLO"];
Union types
A union declares a closed set of types a value may hold. You declare one with the union keyword, listing the case types as parameters:
// Requires the .NET 11 SDK (C# 15): UnionAttribute and IUnion ship with .NET 11.
Pet pet = new Dog("Rex");
// The compiler knows the full set — the switch is exhaustive, no default arm
string name = pet switch
{
Dog d => d.Name,
Cat c => c.Name,
Bird b => b.Name,
};
public record class Cat(string Name);
public record class Dog(string Name);
public record class Bird(string Name);
public union Pet(Cat, Dog, Bird);
The compiler turns a union declaration into a struct: it is marked with the [Union] attribute, implements System.Runtime.CompilerServices.IUnion, and stores the active case in a single field. Only switch expressions get exhaustiveness checking — a plain switch statement and an if/else chain produce no warning.
Some features from the proposal specification are not implemented yet. They are coming in later previews.
Closed hierarchies and the rest
Alongside union types, C# 15 adds closed hierarchies (the closed modifier fixes the set of direct descendants), extension indexers, labeled break and continue, and work on the updated memory-safety model.
What arrived earlier
The field keyword is not new in C# 15 — it shipped with C# 14 in .NET 10.
public class User
{
public string Name
{
get => field;
set => field = value?.Trim() ?? throw new ArgumentNullException(nameof(value));
}
}
ASP.NET Core 11 and Blazor
New Blazor components
<DisplayName>— renders a property name from[Display]and[DisplayName]attributes;[Display]takes precedence and additionally provides a resource type for localization<BasePath>— renders the<base href>tag automatically, without managing the base path by hand- Relative navigation — a new
RelativeToCurrentUriparameter onNavigationManager.NavigateToandNavLink(defaultfalse): the URI is resolved against the current page path rather than the application's base URI - TempData — data that persists between HTTP requests during static SSR: registered automatically when
AddRazorComponents()is called, exposed as a cascadingITempDatavalue; the default provider is cookie-based and encrypted through Data Protection, withMicrosoft.AspNetCore.Components.Endpoints.SessionStorageTempDataProvider(enabled viaTempDataProviderType.SessionStorage) as an alternative - Blazor Web worker template — the
blazorwebworkertemplate for offloading heavy computation off the UI thread
// The worker is created through the generated client
await using var worker = await WebWorkerClient.CreateAsync(JSRuntime);
var result = await worker.InvokeAsync<string>("MyApp.MyWorker.Greet", ["World"]);
In .NET 11 the .NET Web Worker template was renamed to blazorwebworker, and the generated WebWorkerClient gained InvokeVoidAsync for fire-and-forget calls, plus cancellation and timeout support — both for worker creation and for worker invocations.
What else is in ASP.NET Core 11
- OpenAPI 3.2.0 — support for the new specification version, including generated descriptions for binary responses
- Native OpenTelemetry tracing — built in, without an external provider
- Blazor — circuit pausing, the
CacheViewcomponent, built-in validation localization
Breaking Changes
- CoreCLR disables advisory file locking on iOS and tvOS (RC 2).
FileSharerestrictions are no longer enforced on those platforms, because locking in RC 1 could cause the OS to terminate an app entering the background. If you rely on file locks, restore the previous behavior with theDOTNET_SYSTEM_IO_DISABLEFILELOCKING=0environment variable - Runtime Async requires an explicit opt-in — project behavior only changes once you enable
<Features>runtime-async=on</Features>, and you should enable it deliberately rather than "by default"
How to upgrade
# 1. Check that the SDK is installed
dotnet --list-sdks
# 2. Pin the SDK version in global.json
dotnet new globaljson --sdk-version 11.0.100-rc.2 --allow-prerelease
# After GA (expected November 2026):
# dotnet new globaljson --sdk-version 11.0.100 --roll-forward latestFeature
# 3. Update the target framework in the csproj
# <TargetFramework>net10.0</TargetFramework>
# → <TargetFramework>net11.0</TargetFramework>
# 4. Run the upgrade assistant
dotnet tool install -g upgrade-assistant
upgrade-assistant upgrade YourProject.csproj
# 5. Run the tests
dotnet test
Evaluate Runtime Async separately: enable it for a single project, take measurements before and after, and only then decide whether to move your dependencies over.
Conclusion
.NET 11 is a release with concrete changes, not with a general promise of speed. In practice it is: a preview mechanism for runtime async with an explicit opt-in, stabilized C# 15 with union types and closed hierarchies, a set of new Blazor components, OpenAPI 3.2.0, and native OpenTelemetry tracing.
Performance here is a matter of your own measurements. There are no release-wide percentages in the official materials, and substituting press-release numbers for them means telling your readers something false.
Have questions about upgrading to .NET 11? Reach out — I'd love to help.



