Rate Limiting in ASP.NET Core APIs: Prevent Abuse, DoS, and Performance Issues

Rate limiting in ASP.NET Core APIs to prevent abuse, DoS attacks, and performance issues
Visual representation of rate limiting in ASP.NET Core APIs to protect against abuse, DoS attacks, and performance issues.

Introduction

Public APIs are constantly exposed to abuse. Sometimes the abuse is intentional, like Denial of Service (DoS) attacks. Sometimes it is accidental, like a buggy client sending thousands of requests per second. Either way, without protection, your ASP.NET Core API can slow down, crash, or become unavailable for real users.

This is where rate limiting becomes essential.

Rate limiting controls how many requests a client can make within a specific time window. It protects your API from abuse, improves stability, and ensures fair usage across users.

In this guide, you will learn rate limiting in ASP.NET Core from fundamentals to production-ready implementation. We will cover built-in rate limiting, strategies, configuration, real-world use cases, and common mistakes—everything a senior .NET developer is expected to know.


What Is Rate Limiting?

Rate limiting is a technique that restricts the number of API requests a client can make in a given period.

Examples:

  • 100 requests per minute per user
  • 10 requests per second per IP
  • 5 login attempts per minute

When the limit is exceeded, the server responds with:

HTTP 429 – Too Many Requests

This simple mechanism prevents:

  • API abuse
  • Resource exhaustion
  • Performance degradation
  • Unfair usage

Why Rate Limiting Is Critical for ASP.NET Core APIs

Prevents DoS and Brute-Force Attacks

Attackers often overwhelm APIs with massive traffic. Rate limiting stops excessive requests before they reach business logic.

Protects Expensive Endpoints

Endpoints like:

  • File uploads
  • Report generation
  • Authentication
  • Payment processing

should never allow unlimited requests.

Improves API Stability

Rate limiting ensures predictable load, which keeps CPU, memory, and database usage under control.

Required in Real-World Systems

Most production APIs—especially public and partner APIs—must enforce rate limits to remain reliable.


Common Rate Limiting Strategies

Before implementing rate limiting, you should understand the most common strategies.

Fixed Window Rate Limiting

Allows a fixed number of requests in a fixed time window.

Example:

  • 100 requests per minute

Simple but can cause traffic spikes at window boundaries.


Sliding Window Rate Limiting

Tracks requests over a rolling time window instead of fixed intervals.

Example:

  • Last 60 seconds

More accurate and fair than fixed windows.


Token Bucket Algorithm

Requests consume tokens from a bucket that refills over time.

Benefits:

  • Allows short bursts
  • Maintains average request rate

This is widely used in modern APIs.


Concurrency Limiting

Limits the number of concurrent requests, not total requests.

Useful for:

  • Long-running operations
  • File uploads
  • Report generation

Rate Limiting in ASP.NET Core (Built-in Support)

ASP.NET Core provides native rate limiting middleware, which is efficient and easy to configure.

Why Use Built-in Rate Limiting?

  • No third-party dependencies
  • Integrated into the middleware pipeline
  • Supports multiple strategies
  • Highly performant

Enabling Rate Limiting in ASP.NET Core

Step 1: Add Rate Limiting Services

builder.Services.AddRateLimiter(options =>
{
    options.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
});

This sets the default response when the limit is exceeded.


Step 2: Configure a Rate Limiting Policy

Fixed Window Example

builder.Services.AddRateLimiter(options =>
{
    options.AddFixedWindowLimiter("FixedPolicy", limiterOptions =>
    {
        limiterOptions.PermitLimit = 100;
        limiterOptions.Window = TimeSpan.FromMinutes(1);
        limiterOptions.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
        limiterOptions.QueueLimit = 0;
    });
});

This configuration allows:

  • 100 requests per minute
  • No queuing beyond the limit

Step 3: Enable Middleware

app.UseRateLimiter();

⚠️ Important:
Always place rate limiting early in the middleware pipeline, before authentication and business logic.


Applying Rate Limiting to Endpoints

Apply Rate Limiting to All Endpoints

app.MapControllers().RequireRateLimiting("FixedPolicy");

Apply Rate Limiting Per Endpoint

app.MapGet("/api/data", () => "Secure Data")
   .RequireRateLimiting("FixedPolicy");

This approach gives you fine-grained control over API behavior.


IP-Based Rate Limiting

IP-based rate limiting is useful for anonymous or public APIs.

Example: Token Bucket Per IP

options.AddTokenBucketLimiter("IpPolicy", limiterOptions =>
{
    limiterOptions.TokenLimit = 50;
    limiterOptions.TokensPerPeriod = 10;
    limiterOptions.ReplenishmentPeriod = TimeSpan.FromSeconds(10);
    limiterOptions.AutoReplenishment = true;
});

This allows:

  • Short bursts
  • Controlled refill rate

User-Based Rate Limiting

Authenticated APIs should rate-limit per user, not per IP.

Why User-Based Limits Matter

  • Multiple users may share one IP
  • Mobile networks rotate IPs
  • Fair usage per account

Example Concept

Use:

  • User ID
  • API key
  • JWT claim

as the partition key when applying rate limiting.


Rate Limiting for Authentication Endpoints

Login endpoints are prime targets for abuse.

Recommended Limits

  • 5–10 attempts per minute per user
  • Temporary lockout after repeated failures

Why This Matters

Rate limiting authentication:

  • Prevents brute-force attacks
  • Protects user accounts
  • Reduces audit and security incidents

Handling Rate Limit Responses Properly

When the limit is exceeded, return meaningful headers.

Example Response

HTTP/1.1 429 Too Many Requests
Retry-After: 60

Why Headers Matter

Clients can:

  • Retry gracefully
  • Avoid aggressive retries
  • Improve user experience

Distributed Rate Limiting (Important for Scaling)

The Problem

In multi-instance deployments:

  • Each server tracks limits independently
  • Users can bypass limits by hitting different instances

The Solution

Use centralized storage, such as:

  • Redis
  • Distributed cache

This ensures consistent rate limiting across all instances.


Rate Limiting vs Throttling

These terms are often confused.

Rate Limiting

  • Rejects requests beyond the limit
  • Returns 429
  • Protects the system

Throttling

  • Slows down requests
  • Queues or delays responses
  • Maintains availability

In practice, APIs often use both together.


Common Mistakes to Avoid

Applying One Limit to All Endpoints

Different endpoints have different costs. Authentication, uploads, and reports should have stricter limits.


Rate Limiting After Heavy Middleware

Always apply rate limiting before:

  • Database access
  • External API calls
  • File processing

Ignoring Client Feedback

Not returning Retry-After headers leads to poor client behavior and retry storms.


Forgetting About Distributed Environments

Rate limiting must work across instances, not just locally.


Interview Tip: How to Answer Rate Limiting Questions

If asked:

“How do you protect ASP.NET Core APIs from abuse?”

A strong answer:

  1. Explain rate limiting
  2. Mention built-in middleware
  3. Discuss strategies (fixed, sliding, token bucket)
  4. Talk about IP vs user-based limits
  5. Mention distributed rate limiting with Redis

This shows architecture-level thinking.


Real-World Use Cases

Rate limiting is commonly applied to:

  • Public APIs
  • Login and OTP endpoints
  • File uploads
  • Report generation
  • Payment and checkout APIs

Any endpoint that is expensive or sensitive should be rate-limited.


Conclusion

Rate limiting is not an optional feature—it is a core API security and performance requirement.

With proper rate limiting:

  • Your APIs remain stable
  • Abuse is controlled
  • Infrastructure costs stay predictable
  • User experience improves

ASP.NET Core makes rate limiting simple, powerful, and scalable. When you apply it correctly, you move from writing APIs to engineering reliable systems.


❓ FAQ: Rate Limiting in ASP.NET Core APIs

❓ What is rate limiting in ASP.NET Core?

Rate limiting in ASP.NET Core restricts how many requests a client can send to an API within a defined time window. It helps prevent abuse, improves performance, and protects APIs from DoS attacks.


❓ What HTTP status code is returned when rate limiting is exceeded?

ASP.NET Core returns HTTP 429 – Too Many Requests when the configured rate limit is exceeded. This response may also include a Retry-After header.


❓ Does ASP.NET Core support rate limiting out of the box?

Yes. ASP.NET Core provides built-in rate limiting middleware that supports fixed window, sliding window, token bucket, and concurrency limiting strategies without third-party libraries.


❓ What is the best rate limiting strategy for APIs?

There is no single best strategy:

  • Fixed window is simple
  • Sliding window is more accurate
  • Token bucket allows bursts
  • Concurrency limiting protects long-running operations

Most production APIs use token bucket or sliding window.


❓ Should rate limiting be applied before authentication?

Yes. Rate limiting should be applied early in the middleware pipeline, usually before authentication and business logic, to stop abusive traffic as soon as possible.


❓ Is IP-based rate limiting enough?

IP-based rate limiting works for public APIs, but it is not sufficient for authenticated systems. User-based or API key–based rate limiting provides more accurate and fair control.


❓ How do I implement rate limiting in a load-balanced environment?

In multi-instance deployments, rate limiting must use centralized storage such as Redis or distributed cache. Otherwise, users can bypass limits by hitting different servers.


❓ What endpoints should always be rate limited?

Endpoints that should always have rate limiting:

  • Login and authentication
  • OTP and password reset
  • File uploads
  • Payment and checkout
  • Report generation

❓ Is rate limiting the same as throttling?

No.

  • Rate limiting rejects requests beyond a limit
  • Throttling slows or queues requests

Many systems use both together.


Related Articles

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top