Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

To rate-limit an ASP.NET Core Web API, register policies with AddRateLimiter, add the middleware with UseRateLimiter, and apply a global or named policy. Choose a time-based limiter for request volume or a concurrency limiter for simultaneous work. For endpoint-specific policies, put UseRateLimiter after UseRouting. Then load test the application and tune the policy for the actual workload.

Register and apply a rate-limiting policy

ASP.NET Core’s rate-limiting middleware can apply a policy to the whole application or to selected endpoints. Register policies during service configuration, then add the middleware to the request pipeline. This illustrative example shows the placement and named-policy pattern; it intentionally leaves the permit limit and window for you to choose from workload evidence.

builder.Services.AddRateLimiter(options =>
{
    options.AddFixedWindowLimiter("api", limiter =>
    {
        limiter.PermitLimit = /* choose from workload evidence */;
        limiter.Window = TimeSpan.FromMinutes(/* chosen interval */);
        limiter.QueueLimit = 0;
    });
});

var app = builder.Build();
app.UseRouting();
app.UseRateLimiter();
app.MapControllers().RequireRateLimiting("api");

The sample’s zero queue is a configuration choice, not a universal recommendation. Microsoft’s example limits and queue sizes demonstrate API usage; they are not production defaults. Select values based on endpoint cost and observed traffic, and test how the application behaves when the limit is reached.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Global or named policy?

  • Global limiter: use it when the same rule should cover all endpoints. A global-only setup can call UseRateLimiter before routing.
  • Named policy: use it when endpoints or groups need different rules. Attach a named policy with RequireRateLimiting("policy-name"), or use the documented EnableRateLimitingAttribute.

Endpoint-specific policies rely on endpoint selection and metadata, so call UseRateLimiter after UseRouting. The middleware must be in the pipeline for the registered policy to take effect.

Choose a limiter for the resource you need to protect

Rate limiting is not one algorithm. Time-based limiters constrain requests over intervals; concurrency limiting caps how many requests can be in progress simultaneously. Decide according to the endpoint’s resource costs, such as CPU, database work, I/O, and request duration.

Limiter What it constrains Useful when
Fixed window Requests within a fixed interval; the counter resets when the interval ends. A simple periodic reset fits the endpoint’s traffic pattern.
Sliding window Requests across a moving interval divided into segments; requests in expired segments are recycled as the window advances. A moving interval is more suitable than a fixed reset.
Token bucket Requests against a supply of tokens replenished periodically up to a configured bucket limit. Clients may make bursts, but should then be constrained by token replenishment.
Concurrency Simultaneous requests, not request volume over a time period. The main risk is too many expensive operations running at once.

No limiter is best for every API. A time-based limit and a concurrency cap address different forms of load, so select the behavior that matches the failure mode you are trying to prevent.

Partition limits carefully

A partitioned policy gives separate buckets to different keys. Depending on the API, a key could be a user identity, client IP address, API key, or endpoint path. This can provide finer control than treating every request as one shared pool, but the key determines who shares a limit and who gets a separate one.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Derive keys from deliberate, bounded inputs. Microsoft warns that partitioning on unbounded user-controlled values can exhaust memory: an attacker or client could cause the application to create a large number of distinct partitions. Avoid using arbitrary request data as a partition key unless the application constrains it.

Handle rejected requests and retry guidance

Use the limiter’s OnRejected callback to customize what happens when a request is rejected. The response body and status details are part of your API contract; Microsoft’s examples do not prescribe one universal response format. Keep the response consistent with your clients’ error handling and retry behavior.

For fixed-window, sliding-window, and token-bucket limiters, Microsoft’s samples use RetryAfter to provide an estimate of when permits may be added. A concurrency limiter cannot calculate when a permit will become available, so do not promise clients an exact retry time for that case. Clients should avoid tight retry loops; coordinate retry guidance with the API’s chosen policy and response contract.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Check framework compatibility before migrating

The built-in rate-limiting APIs are documented for ASP.NET Core 7.0 through 11.0. Check the API reference for the framework version targeted by your application, particularly when using partition factories or moving between major versions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The separate ConcurrencyLimiter middleware was marked obsolete in ASP.NET Core 8 because its functionality is covered by the rate-limiting middleware built on System.Threading.RateLimiting APIs. Microsoft’s breaking-change guidance documents removal for ASP.NET Core 11 and describes a transitional Microsoft.AspNetCore.ConcurrencyLimiter 9.x or 10.x NuGet package for applications targeting net11.0 that cannot migrate immediately. Consult the current migration guidance for the target version before relying on that transition package.

Test the policy before deployment

A configured limit is not evidence that the limit suits production. Microsoft says, “Apps using rate limiting should be carefully load tested and reviewed before deploying,” in its ASP.NET Core rate-limiting middleware guidance. Test both normal traffic and rejected-request behavior, including the effects of queues, partitioning, and expensive endpoints. The appropriate limits depend on the workload; the documentation’s sample values do not establish safe limits or performance gains for a particular API.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.