Skip to content
BytePatterns

Rate Limiting

System Design: lesson 12 of 17

Cap the flow before it caps your service.

Lesson 12 of 17 · 5 min

Rate Limiting

Step 1 of 11

A limiter counts requests per caller and rejects the excess. First, identify who is asking.

The Idea

A rate limiter counts requests per client and rejects the excess, normally with 429 and a Retry-After header saying when to come back. A token bucket refills at a steady rate up to a maximum, so a client may burst up to the bucket size, then settles to the refill rate.

Real-World Example

A council recycling centre allows each household twelve visits a year and at most three in any one week. You can clear a whole garage over a weekend, but you cannot do it every weekend — exactly the shape of a bucket that refills slowly and only holds so much.

The Tradeoff

Limits protect the service and punish legitimate bursts, and a counter shared across many servers costs a round trip on every request. A fixed window is the cheapest to build and the easiest to abuse: a client can spend a full budget either side of the boundary.

limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
location /api/ {
    limit_req zone=api burst=20 nodelay;   # 10/s sustained, 20 in hand
    limit_req_status 429;
}

Your turn

Put the steps in the right order.

  1. Reject with 429 and a Retry-After header once the bucket is empty
  2. Identify the caller: API key, account, or address
  3. Spend one token if the bucket holds at least one
  4. Refill that caller's bucket for the time since their last request

Mini quiz

1 / 3

The status code for a throttled request is:

New lessons land every few weeks

Leave an address and we will tell you when the next one is up. That is the only reason we will use it.

One address, stored so we can email you. Nothing else, ever.