In the world of web APIs, especially public ones, controlling how many requests a user or client can make is very important. This is known as API Rate Limiting. Without it, one careless or malicious user could overload your server, slow down services for others, or even bring down your entire application.
Let’s understand this concept deeply, see how it works in .NET, and explore some best scenarios, real examples, and even interview questions that can help you.
What is API Rate Limiting?
Simply put, Rate Limiting controls how often someone (like a user, client, or IP address) can make requests to an API within a specific period.
For example
- A public API may allow 100 requests per minute per user.
- If someone sends 101 requests, the 101st will be rejected or delayed.
This protects the backend and ensures fair usage by all clients.
Why Do We Need API Rate Limiting?
- Avoid Server Overload: Prevents your server from crashing due to too many requests.
- Stops Abuse: Blocks bots or malicious users from hammering your API.
- Ensures Fair Usage: All users get a fair share of the service.
- Reduces Cost: If you're using cloud services (like Azure/AWS), more requests mean more cost.
- Enhances Security: Prevents brute-force attacks, especially on login APIs.
API Rate Limiting in .NET
.NET provides simple and flexible ways to implement rate limiting, especially since .NET 7 and .NET 8, where a built-in Rate Limiting Middleware was introduced.
Setting Up Rate Limiting in ASP.NET Core 8
You can add rate limiting using the built-in AspNetCore.RateLimiting
package.
1. Install NuGet Package (if required)
dotnet add package AspNetCoreRateLimit
2. Configure in Program.cs
builder.Services.AddMemoryCache();
builder.Services.Configure<IpRateLimitOptions>(builder.Configuration.GetSection("IpRateLimiting"));
builder.Services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
builder.Services.AddInMemoryRateLimiting();
In appsettings.json
"IpRateLimiting": {
"EnableEndpointRateLimiting": true,
"StackBlockedRequests": false,
"RealIpHeader": "X-Real-IP",
"ClientIdHeader": "X-ClientId",
"HttpStatusCode": 429,
"GeneralRules": [
{
"Endpoint": "*",
"Period": "1m",
"Limit": 5
}
]
}
✔️ This will limit each client to 5 requests per minute for all endpoints (*
).
Alternate way
using Microsoft.AspNetCore.RateLimiting;
using System.Threading.RateLimiting;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRateLimiter(options =>
{
options.AddFixedWindowLimiter("fixed", opt =>
{
opt.Window = TimeSpan.FromSeconds(10);
opt.PermitLimit = 5; // Allow 5 requests every 10 seconds
opt.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
opt.QueueLimit = 2; // Maximum 2 requests will wait in queue
});
});
var app = builder.Build();
app.UseRateLimiter();
app.MapGet("/", () => "Hello!").RequireRateLimiting("fixed");
app.Run();
Explanation
- Window: Time window to measure requests.
- PermitLimit: Number of requests allowed.
- QueueLimit: Extra requests to wait in the queue.
- RequireRateLimiting("fixed"): Apply this policy to specific endpoints.
Real-world Scenarios (Where Rate Limiting Helps)
- Public APIs like weather, currency exchange, etc.
- Prevents free users from abusing the API.
- Login & Authentication endpoints
- Stops brute-force attacks.
- Payment Gateway APIs
- Limits transaction requests to avoid fraud.
- Microservices architecture
- One service calling another repeatedly can exhaust system resources.
Example Use Case
Imagine a Matrimony Application API:
- Free users: Max 20 requests/minute.
- Premium users: Max 100 requests/minute.
This ensures premium users get faster service without being affected by free users’ heavy traffic.
How to do this?
Use user roles or JWT claims inside the limiter logic to apply different limits dynamically.
How to Handle Clients Exceeding Limits?
When a client hits the limit:
- 429 Too Many Requests HTTP status code is returned.
- Optionally, include a
Retry-After
header to inform them when they can try again.
Example response
HTTP/1.1 429 Too Many Requests
Retry-After: 30
Best Practices for API Rate Limiting
- ✅ Set different limits for different users (e.g., free vs. paid).
- ✅ Always log when limits are hit (for audit or debugging).
- ✅ Notify clients properly with error codes and retry headers.
- ✅ Use Redis or distributed caches for scalable limits across multiple servers.
- ✅ Don't forget internal APIs or microservices calls — they may also need limits.
Common Interview Questions (with Answers)
Q 1. Why is Rate Limiting important in APIs?
A. It prevents misuse, protects backend resources, avoids server overload, and ensures fair usage among clients.
Q 2. How do you implement Rate Limiting in .NET Core?
A. Using the AspNetCore.RateLimiting
middleware. Configure policies (FixedWindow, SlidingWindow, TokenBucket, Concurrency) in the Program.cs
file and apply them to endpoints using .RequireRateLimiting("policyName")
.
Q 3. What is the difference between Fixed Window and Sliding Window rate limiting?
A
- Fixed Window: Limits apply to fixed time blocks (e.g., 10 requests every minute).
- Sliding Window: Limits apply to rolling periods — more accurate but slightly complex.
Q 4. What HTTP status code is used when a rate limit is hit?
A. 429 Too Many Requests.
Q 5. Can Rate Limiting be role-based?
A. Yes. You can set different limits based on user roles, API keys, or tokens using custom resolvers or policies.
Conclusion
Rate limiting is no longer optional — it’s a must-have feature for all APIs. In .NET, adding rate limiting is now super simple thanks to the built-in middleware. Whether you’re building small internal tools or large public services, a proper rate-limiting strategy will protect your application from abuse and ensure reliability.