What's New in .NET 7: A Friendly Guide for Beginners
A simple, student-friendly tour of the biggest .NET 7 features: speed boosts, Native AOT, C# 11, rate limiting, and minimal API upgrades.
When .NET 7 arrived in November 2022, it was a big step forward for the whole .NET family. It is a little old now. In 2026, .NET 10 is the long-term support (LTS) release and C# 14 has shipped. But .NET 7 is still a wonderful story to learn. Many ideas you use today were born or grew up here. This guide walks you through it slowly and kindly.
A everyday way to picture it
Imagine your family runs a small tiffin (lunchbox) delivery service in your city. Every year you try to make the kitchen a little better.
- One year you buy a faster stove. Food cooks quicker. (That is like performance improvements.)
- One year you learn to pack the dabba so it is lighter and opens faster for the customer. (That is like Native AOT making a smaller, faster-starting app.)
- One year you add a rule: only 50 orders per hour, so the kitchen never gets flooded. (That is like rate limiting.)
- One year you find a neater way to write the order slips so they are easy to read. (That is like the new C# 11 language features.)
.NET 7 did all four of these things at once. Let us look at each, step by step.
First, what does a .NET release even mean?
.NET ships one big release every November. Each release has three parts that grow together:
- The runtime that actually runs your program.
- The libraries full of ready-made code (like lists, files, and web servers).
- The C# language version that you write your code in.
So when we say "What's new in .NET 7", we really mean new things across all three. Here is the simple map.
| Part | .NET 7 brought |
|---|---|
| Runtime | On-Stack Replacement, dynamic PGO, faster startup |
| Libraries | Rate limiting, faster regex, better JSON |
| Language (C# 11) | Raw strings, required members, list patterns |
| Web (ASP.NET Core) | Rate limiter middleware, output caching, faster Kestrel |
Theme 1: Speed, speed, speed
The team said it plainly: every part of .NET 7 was built with performance in mind. Two runtime features are the stars.
On-Stack Replacement (OSR)
Your code does not run at full speed the moment it starts. The runtime first compiles a quick, simple version so the app can begin fast. Then, while the program runs, it watches the "hot" parts (the code that runs again and again) and quietly swaps in a faster version.
The problem before .NET 7: a method already running in a long loop could not be upgraded until it finished. With On-Stack Replacement, the runtime can now upgrade a method in the middle of its work, even while it is stuck in a long loop.
Think of it like changing a slow auto-rickshaw for a fast car while you are still riding, without stopping the journey.
Dynamic PGO (Profile-Guided Optimization)
PGO means the runtime watches how your program actually behaves, then optimizes for the real pattern. For example, if one branch of an if runs 99% of the time, the runtime makes that path extra fast.
You do not have to write any special code for these. You just upgrade to .NET 7 and your program runs faster. That is the best kind of feature.
Theme 2: Native AOT (smaller, faster-starting apps)
Normally a .NET app ships as instructions that get turned into machine code while it runs (this is called JIT, Just-In-Time). That is flexible, but it costs a little time at startup.
Native AOT (Ahead-Of-Time) flips this. It compiles your program all the way to native machine code before you ship it. The result is a single standalone file with no JIT inside.
Why is this exciting?
- Fast startup. One example showed startup and shutdown dropping from about 350ms down to about 45ms.
- Small size. No extra runtime files to drag along.
- Self-contained. One file you can copy and run.
This is perfect for tiny cloud services and command-line tools that must start instantly.
JIT build vs Native AOT build
Steps
Your C# code
The same source you write
JIT app
Compiled to machine code as it runs
Native AOT app
Compiled to native code before shipping; tiny and fast to start
In .NET 7, Native AOT first arrived for console apps. (Later, in .NET 8, it grew to support ASP.NET Core minimal APIs too.) Here is a tiny console program you could publish with AOT.
// Program.cs — a small console app
Console.WriteLine("Namaste from a Native AOT app!");
int total = 0;
for (int i = 1; i <= 10; i++)
{
total += i;
}
Console.WriteLine($"Sum of 1 to 10 is {total}.");To publish it ahead-of-time, you add one line to your project file and run a publish command.
<!-- MyApp.csproj -->
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>Then on the command line you would run a publish command and get a single native file. Not every library works with AOT, because some use tricks (like heavy reflection) that need the JIT. But for simple, fast tools, it is a great fit.
Theme 3: Built-in rate limiting
Picture a popular new mobile recharge website on the first day of a big sale. If a million people press the button at the same second, the server can fall over. Rate limiting is the polite bouncer at the door. It says: "Only this many requests at a time, please."
Before .NET 7, you wrote this yourself or used a library. Now it is built in, through the System.Threading.RateLimiting package and ASP.NET Core middleware. There are four ready-made algorithms.
| Algorithm | Plain-English idea | Good for |
|---|---|---|
| Fixed Window | "100 requests every 1 minute, then reset." | Simple limits |
| Sliding Window | Like fixed, but the window slides smoothly. | Fairer bursts |
| Token Bucket | A bucket refills tokens over time; each request spends one. | Allowing short bursts |
| Concurrency | "Only 10 requests inside at once." | Protecting slow work |
Here is how you might add a fixed-window limiter to a web app. Notice the route /orders is protected.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRateLimiter(options =>
{
options.AddFixedWindowLimiter("fixed", limiter =>
{
limiter.PermitLimit = 100; // 100 requests
limiter.Window = TimeSpan.FromMinutes(1); // every minute
limiter.QueueLimit = 5; // a small waiting line
});
});
var app = builder.Build();
app.UseRateLimiter();
app.MapGet("/orders", () => "Here are your orders")
.RequireRateLimiting("fixed");
app.Run();When the limit is crossed, callers get a 429 Too Many Requests reply instead of crashing your server. Let us picture the decision the bouncer makes.
Theme 4: C# 11, the neater language
The language got several friendly upgrades. Here are the ones beginners love most.
Raw string literals
Old C# strings were painful when you wanted quotes or backslashes inside, like JSON or file paths. You had to "escape" everything with \. Raw string literals fix this. You wrap your text in three or more double quotes, and everything inside is taken as-is.
// Old, escaped way — hard to read
string oldJson = "{ \"name\": \"Asha\", \"city\": \"Pune\" }";
// New raw string — what you see is what you get
string newJson = """
{
"name": "Asha",
"city": "Pune"
}
""";
Console.WriteLine(newJson);No more messy backslashes. This is great for JSON, SQL, HTML, and file paths.
Required members
Sometimes an object is meaningless without certain values. A Student with no name makes no sense. The new required keyword tells the compiler: "You must set this when you create the object, or I will refuse to build."
public class Student
{
public required string Name { get; set; }
public required int RollNumber { get; set; }
public string? Hobby { get; set; } // optional
}
// This is fine:
var asha = new Student { Name = "Asha", RollNumber = 12 };
// This would NOT compile — Name and RollNumber are missing:
// var broken = new Student { Hobby = "Cricket" };This catches mistakes early, at compile time, instead of crashing later when the app runs.
List patterns
Pattern matching learned to look inside a list. You can now check the shape of a list and even grab parts of it.
int[] numbers = { 1, 2, 3 };
string description = numbers switch
{
[] => "empty list",
[var single] => $"one item: {single}",
[var first, .., var last] => $"starts with {first}, ends with {last}",
};
Console.WriteLine(description); // starts with 1, ends with 3The .. means "any number of items in the middle". This makes some checks much shorter and clearer.
Generic math
This is a more advanced one. C# 11 lets interfaces have static abstract members, which unlocked generic math. Now you can write one method that adds up any number type, int, double, decimal, all at once, using the INumber<T> interface. Before, you had to copy the same method for every type. This is more for library authors, but it is a quiet, powerful change.
How the pieces fit together
If you build a small web service in .NET 7, several of these features can work side by side. Here is the journey of one request.
A request through a .NET 7 web service
Steps
User click
Browser sends a request
Rate limiter
Bouncer checks the limit
Your code
Written cleanly with C# 11
Fast runtime
OSR and PGO make hot paths quick
Response
Answer sent back fast
A quick note on the bigger ecosystem
Some popular libraries you may read about have changed since .NET 7. For example, MediatR and MassTransit are now commercially licensed. They were free and open for years, but their newer versions need a paid license for many companies. If you see them in old .NET 7 tutorials, that is fine to learn from, but check the license before using them in a real product today.
This is a good lesson: the .NET world keeps moving. A feature or library that was "the way" in 2022 may have a different story in 2026.
Should you use .NET 7 today?
Honestly, for brand-new work, no. .NET 7 was a Standard Term Support release. Its support window has ended. In 2026 you should reach for a current release. .NET 10 is the LTS (long-term support) version, and C# 14 has shipped. There is even a .NET 11 preview where C# 15 brings union types.
So why learn .NET 7 at all? Because it is where many of today's ideas grew up. Understanding OSR, AOT, rate limiting, and C# 11 helps you understand the newer releases that build directly on top of them.
Quick recap
- .NET 7 shipped in November 2022 with a strong focus on speed.
- On-Stack Replacement and dynamic PGO make your code faster automatically, with no work from you.
- Native AOT (for console apps in .NET 7) builds a small, single-file app that starts very fast.
- Rate limiting is now built in, with four algorithms: fixed window, sliding window, token bucket, and concurrency.
- C# 11 added raw string literals,
requiredmembers, list patterns, and generic math. - .NET 7 is an STS release whose support has ended. For new projects, use a current LTS like .NET 10 with C# 14.
- Watch licenses: MediatR and MassTransit are now commercially licensed.
References and further reading
- What's new in .NET 7 — Microsoft Learn
- What's new in ASP.NET Core in .NET 7 — Microsoft Learn
- Announcing Rate Limiting for .NET — .NET Blog
- Native AOT deployment overview — Microsoft Learn
- C# 11 — The history of C# — Microsoft Learn
- Performance Improvements in .NET 7 — .NET Blog
Related Posts
10 Reasons to Upgrade to .NET 9: A Friendly Guide for Developers
Ten simple, real reasons to upgrade your app to .NET 9 — faster runtime, smaller Docker images, smarter GC, new LINQ, AI helpers and more.
New Features in C# 13: A Friendly Beginner's Guide
Learn the new features in C# 13 with simple words, real-life examples, diagrams, and code you can read in minutes. Great for beginners.
Make Your ASP.NET Core Web API 18x Faster with HybridCache
Learn how HybridCache in .NET 9 speeds up your ASP.NET Core Web API up to 18x, with L1/L2 caching, stampede protection, and tags, explained simply.
How I Optimized an API Endpoint to Make It 15x Faster
A simple, step-by-step story of how I made a slow ASP.NET Core API endpoint 15x faster using EF Core projection, AsNoTracking, paging, and indexes.
Building High-Performance .NET Apps With C# Channels
Learn C# Channels in .NET 10 with simple examples. Pass data safely between producers and consumers and build fast, smooth, high-performance apps.
Understanding Change Tracking for Better Performance in EF Core
Learn how EF Core change tracking works, the entity states it uses, and simple tricks like AsNoTracking to make your .NET apps faster.