DEV Community

Suresh Thotakura
Suresh Thotakura

Posted on AI-assisted

A Rate Limiter That Knows Who's Calling

ASP.NET Core's rate limiter partitions however you key it. Key it on the caller, and one client's burst stops being every other client's problem.

I built a small lab to get that wiring right end to end.

Four stages:

  1. Authenticate. A custom header scheme validates the client and issues a client_id claim. Nothing downstream can partition per client until this exists.

  2. Partition. The policy reads that claim and keys the partition by client id plus HTTP verb. A client's read budget and write budget are separate buckets, and so are two different clients'.

  3. Limit. Fixed window: 10 requests per 10 seconds, queue limit 0. No waiting in line, you either get a permit or you don't.

  4. Enforce. Request 11 in the window gets HTTP 429.

The client's profile decides which partition it lands in:

Standard: limited on every verb.
Premium: reads skip the limiter, writes still get 10 per 10 seconds.
Unlimited: no limiter at all.

The part worth remembering is the ordering.
UseRateLimiter() has to run after UseAuthentication() and UseAuthorization(). Register it earlier and the policy executes before the client_id claim exists, so there is nothing to partition on. In this implementation that throws rather than quietly limiting on nothing, which is the failure mode you want: loud, not silent.

Three calls do the wiring: AddRateLimiter() to register the policy, UseRateLimiter() to put it in the pipeline, RequireRateLimiting() to attach it to an endpoint group.

Code, including the in-memory client fixtures and the Todo endpoints it protects: https://github.com/sthotakura/rate-limiter-lab

Top comments (0)