Skip to main content
SEMastery
.NET Corebeginner

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.

11 min readUpdated March 2, 2026

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.

The four big themes of .NET 7, like upgrades to a tiffin kitchen

First, what does a .NET release even mean?

.NET ships one big release every November. Each release has three parts that grow together:

  1. The runtime that actually runs your program.
  2. The libraries full of ready-made code (like lists, files, and web servers).
  3. 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
RuntimeOn-Stack Replacement, dynamic PGO, faster startup
LibrariesRate 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.

How the runtime makes hot code faster while the app keeps running

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

Your C# code
JIT app
Native AOT app

Steps

1

Your C# code

The same source you write

2

JIT app

Compiled to machine code as it runs

3

Native AOT app

Compiled to native code before shipping; tiny and fast to start

Two ways to turn your code into something the computer runs

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.

AlgorithmPlain-English ideaGood for
Fixed Window"100 requests every 1 minute, then reset."Simple limits
Sliding WindowLike fixed, but the window slides smoothly.Fairer bursts
Token BucketA 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.

How a rate limiter decides to allow, queue, or reject a request

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 3

The .. 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

User click
Rate limiter
Your code
Fast runtime
Response

Steps

1

User click

Browser sends a request

2

Rate limiter

Bouncer checks the limit

3

Your code

Written cleanly with C# 11

4

Fast runtime

OSR and PGO make hot paths quick

5

Response

Answer sent back fast

From the user's click to the answer, with .NET 7 features helping along the way

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.

Where .NET 7 sits in the bigger timeline

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, required members, 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

Related Posts