Rate limiting in ASP.NET Core 8 is a built-in middleware feature that controls the number of incoming HTTP requests a client can make within a specified time window. It protects APIs from abuse, prevents denial-of-service attacks, ensures fair usage, and improves overall system stability in high-traffic environments.
With the introduction of the native Rate Limiting middleware in ASP.NET Core, developers no longer need third-party libraries for most rate limiting scenarios. This article provides a complete implementation guide, explains different rate limiting algorithms, demonstrates configuration examples, compares strategies, and discusses production best practices.
Why Rate Limiting Is Important
Without rate limiting:
APIs can be overwhelmed by excessive requests
Systems become vulnerable to brute-force attacks
Infrastructure costs increase
Legitimate users experience degraded performance
With rate limiting:
Traffic is controlled per user/IP/client
API abuse is reduced
Backend systems remain stable
Fair usage policies are enforced
Rate limiting is critical for public APIs, authentication endpoints, payment systems, and microservices architectures.
Built-In Rate Limiting in ASP.NET Core 8
ASP.NET Core 8 provides the Microsoft.AspNetCore.RateLimiting middleware, which supports multiple algorithms:
Fixed Window
Sliding Window
Token Bucket
Concurrency Limiter
To use rate limiting, you must configure services and middleware in Program.cs.
Step 1: Add Rate Limiting Services
In Program.cs:
using System.Threading.RateLimiting;
builder.Services.AddRateLimiter(options =>
{
options.AddFixedWindowLimiter("FixedPolicy", config =>
{
config.PermitLimit = 5;
config.Window = TimeSpan.FromSeconds(10);
config.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
config.QueueLimit = 2;
});
});
This configuration allows:
5 requests every 10 seconds
2 additional queued requests
Oldest queued request processed first
Step 2: Enable Middleware
Add middleware in the request pipeline:
app.UseRateLimiter();
Step 3: Apply Rate Limiting to Endpoints
Apply the policy globally:
app.MapControllers().RequireRateLimiting("FixedPolicy");
Or apply to specific endpoint:
app.MapGet("/limited", () => "Limited endpoint")
.RequireRateLimiting("FixedPolicy");
Fixed Window Rate Limiting
Fixed Window divides time into fixed intervals.
Example:
5 requests per 10 seconds
Counter resets after 10 seconds
Advantages:
Simple to configure
Low overhead
Disadvantages:
Traffic spikes at window boundaries
Sliding Window Rate Limiting
Sliding Window smooths traffic by tracking requests in smaller segments within a rolling window.
Example configuration:
builder.Services.AddRateLimiter(options =>
{
options.AddSlidingWindowLimiter("SlidingPolicy", config =>
{
config.PermitLimit = 10;
config.Window = TimeSpan.FromSeconds(30);
config.SegmentsPerWindow = 3;
config.QueueLimit = 2;
});
});
Advantages:
Smoother traffic distribution
Reduces burst behavior
Disadvantages:
Slightly more complex
Token Bucket Rate Limiting
Token Bucket allows bursts of traffic while maintaining a steady refill rate.
Example configuration:
builder.Services.AddRateLimiter(options =>
{
options.AddTokenBucketLimiter("TokenPolicy", config =>
{
config.TokenLimit = 10;
config.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
config.QueueLimit = 2;
config.ReplenishmentPeriod = TimeSpan.FromSeconds(5);
config.TokensPerPeriod = 5;
config.AutoReplenishment = true;
});
});
Advantages:
Allows short bursts
Ideal for APIs with variable traffic
Disadvantages:
Slightly more configuration required
Concurrency Limiter
Concurrency limiter restricts simultaneous request processing rather than request rate over time.
builder.Services.AddRateLimiter(options =>
{
options.AddConcurrencyLimiter("ConcurrencyPolicy", config =>
{
config.PermitLimit = 3;
config.QueueLimit = 2;
});
});
Useful for:
Heavy processing endpoints
CPU-intensive operations
Join the conversation! Your thoughts help the community grow.