Introduction
Modern APIs are frequently exposed to the internet and may receive thousands of requests every minute. While this is expected for popular applications, excessive requests from a single user, bot, or malicious actor can negatively impact performance and availability.
Rate Limiting helps protect applications by controlling how many requests a client can make within a specific time period.
Common benefits include:
Preventing API abuse
Protecting against brute-force attacks
Improving application stability
Reducing server load
Ensuring fair resource usage
In this article, you'll learn how to implement Rate Limiting in ASP.NET Core applications using the built-in Rate Limiting middleware.
What Is Rate Limiting?
Rate Limiting restricts the number of requests a client can make during a defined time window.
Example:
Limit:
100 Requests
Per:
1 Minute
If the client exceeds the limit:
HTTP 429
Too Many Requests
The request is rejected until the limit resets.
Why Use Rate Limiting?
Consider a public API.
Without rate limiting:
User
↓
10,000 Requests
↓
Server Overload
Potential issues:
High CPU usage
Slow responses
Denial-of-Service attacks
Increased hosting costs
With rate limiting:
User
↓
100 Requests/Minute
↓
Controlled Traffic
The application remains stable and responsive.
Built-In Rate Limiting in ASP.NET Core
Starting with .NET 7, Microsoft introduced built-in Rate Limiting middleware.
Install the package if required:
dotnet add package
Microsoft.AspNetCore.RateLimiting
Most modern ASP.NET Core templates already include the necessary support.
Configure Rate Limiting
In Program.cs, add the service.
using System.Threading.RateLimiting;
builder.Services.AddRateLimiter(
options =>
{
options.AddFixedWindowLimiter(
"fixed",
config =>
{
config.PermitLimit = 100;
config.Window =
TimeSpan.FromMinutes(1);
});
});
This configuration allows:
100 Requests
Per Minute
for each client.
Enable the Middleware
Register the middleware.
app.UseRateLimiter();
This activates rate limiting for the application.
Apply Rate Limiting to Endpoints
Apply the policy to specific endpoints.
app.MapGet("/products", () =>
{
return Results.Ok("Products");
})
.RequireRateLimiting("fixed");
Now the endpoint follows the configured limit.
Global Rate Limiting
You can apply a policy globally.
builder.Services.AddRateLimiter(
options =>
{
options.GlobalLimiter =
PartitionedRateLimiter.Create<
HttpContext, string>(
context =>
RateLimitPartition
.GetFixedWindowLimiter(
"global",
_ => new FixedWindowRateLimiterOptions
{
PermitLimit = 100,
Window = TimeSpan.FromMinutes(1)
}));
});
All requests will use the configured limit.
Fixed Window Rate Limiting
Fixed Window is the simplest strategy.
Example:
Window:
1 Minute
Limit:
100 Requests
If 100 requests are made:
Request 101
↓
Rejected
The counter resets after one minute.
This approach is easy to configure and understand.
Sliding Window Rate Limiting
Sliding Window provides smoother request handling.
Instead of resetting completely:
Previous Window
+
Current Window
ASP.NET Core example:
options.AddSlidingWindowLimiter(
"sliding",
config =>
{
config.PermitLimit = 100;
config.Window =
TimeSpan.FromMinutes(1);
});
This often produces more predictable traffic patterns.
Token Bucket Rate Limiting
Token Bucket is commonly used in APIs.
Concept:
Bucket Contains Tokens
↓
Request Consumes Token
↓
Tokens Refill Over Time
Configuration:
options.AddTokenBucketLimiter(
"token",
config =>
{
config.TokenLimit = 100;
config.TokensPerPeriod = 10;
config.ReplenishmentPeriod =
TimeSpan.FromSeconds(10);
});
This approach supports traffic bursts more effectively.
Custom Response for Blocked Requests
Customize the response when limits are exceeded.
builder.Services.AddRateLimiter(
options =>
{
options.OnRejected =
async (context, token) =>
{
context.HttpContext.Response
.StatusCode = 429;
await context.HttpContext
.Response
.WriteAsync(
"Too many requests",
token);
};
});
Users receive a clear message instead of a generic error.
Real-World Example
Imagine an e-commerce API.
Endpoints:
Product Search
Order Tracking
User Profile
Without rate limiting:
Bot
↓
Thousands Of Requests
↓
Performance Issues
With rate limiting:
Bot
↓
Request Limit Reached
↓
Blocked
Legitimate users continue receiving fast responses.
Best Practices
When implementing rate limiting:
Apply limits to public APIs.
Use stricter limits on authentication endpoints.
Return HTTP 429 for blocked requests.
Monitor rate-limit violations.
Choose the appropriate strategy.
Combine rate limiting with authentication and logging.
Test limits under production-like traffic.
These practices help improve security and reliability.
Advantages of Rate Limiting
Rate Limiting offers several benefits:
Prevents abuse
Protects server resources
Improves API stability
Enhances security
Reduces denial-of-service risks
Ensures fair usage
These benefits are especially important for public-facing APIs.
Conclusion
Rate Limiting is an essential feature for modern ASP.NET Core applications. It helps protect APIs from abuse, controls traffic, and improves overall application reliability.
With the built-in Rate Limiting middleware introduced in .NET 7, implementing request throttling has become much simpler. Whether you choose Fixed Window, Sliding Window, or Token Bucket strategies, rate limiting provides an effective way to manage traffic and protect your services.
For production applications, combining rate limiting with authentication, monitoring, and logging creates a stronger and more resilient API architecture.

Join the conversation! Your thoughts help the community grow.