nginx limit_req
limit_req is the Nginx directive that implements token bucket rate limiting for HTTP requests. It works in conjunction with limit_req_zone, which defines a shared memory zone (the token bucket state) keyed by a variable such as client IP or API key. The rate parameter sets the steady-state refill rate; burst sets the bucket capacity; nodelay processes burst requests immediately rather than queuing them.
Formula
Minimal configuration:
limit_req_zone $http_x_api_key zone=api:10m rate=10r/s;
server {
location /api/ {
limit_req zone=api burst=50 nodelay;
limit_req_status 429;
add_header Retry-After 5 always;
}
}Why it matters in practice
limit_req is the most widely deployed rate limiting mechanism on the internet, running in front of millions of APIs. Misconfiguring it — wrong key variable, missing nodelay, wrong burst value — is a common cause of unexpected 429s or, worse, no rate limiting at all. The limit_req_zone key determines the limiting granularity: $binary_remote_addr limits by IP (compact 4–16 bytes), $http_x_api_key limits by API key header, $http_authorization limits by bearer token.
Common mistakes
- •Not specifying limit_req_status 429 — Nginx defaults to returning 503 for rate-limited requests, which is semantically incorrect.
- •Using $remote_addr instead of $binary_remote_addr for the zone key — the binary form uses 4 bytes per IPv4 address instead of 15, allowing ~2.5× more entries in the same memory zone.
- •Not adding a Retry-After header — the rate-limited client has no signal for when to retry.