Rate limiting caps how many requests a client can make in a given window of time. It is the seatbelt of any public API — it protects your servers from being overwhelmed, stops one noisy client from starving everyone else, and blunts abuse and runaway retry loops. The interesting part is not whether to rate limit, but which algorithm you use to count and enforce the limit.
What changed in 2026
- Distributed rate limiting got easier. Managed stores and edge platforms now offer built-in counters, so enforcing a global limit across many servers no longer requires hand-rolled coordination.
- Adaptive limits appeared. Some systems now tighten limits automatically under load and relax them when capacity frees up, instead of using one fixed number.
- Standardized headers spread. Returning clear
RateLimit headers so clients know their remaining quota and reset time became an expected courtesy, not an afterthought.
The main algorithms
- Fixed window. Count requests per calendar window (for example, 100 per minute). Simple, but allows bursts at window edges.
- Sliding window. Smooth the count over a rolling period to avoid the edge-burst problem of fixed windows.
- Token bucket. A bucket refills tokens at a steady rate; each request spends one. Allows short bursts up to the bucket size while capping the long-run rate.
- Leaky bucket. Requests queue and drain at a fixed rate, smoothing output into a steady stream.
Algorithms compared
| Algorithm |
Allows bursts |
Smoothness |
Complexity |
| Fixed window |
Yes (at edges) |
Low |
Very low |
| Sliding window |
Limited |
Medium |
Medium |
| Token bucket |
Yes (bounded) |
Medium |
Medium |
| Leaky bucket |
No |
High |
Medium |
When to use which
Use fixed window when you want the simplest possible limit and edge bursts are acceptable. Use sliding window when those edge bursts would let clients double their intended rate. Reach for token bucket when you want to allow legitimate short bursts — a user opening several pages at once — while still capping sustained usage; it is the most common general-purpose choice. Use leaky bucket when a downstream system needs a perfectly steady input rate. Rate limiting also pairs with how you spread traffic in the first place, which is where load balancing algorithms come in.
Common pitfalls
- Limiting per server instead of globally. With many servers, a per-instance limit lets clients multiply their real rate by the number of servers. Use a shared counter.
- No informative response. Return HTTP 429 with a
Retry-After header so well-behaved clients back off instead of hammering.
- Rate limiting on the wrong key. Limiting by IP punishes users behind shared NAT; limiting by API key or user is usually fairer. Often you need both.
- Ignoring retries. Aggressive client retries can turn a limit into a self-inflicted stampede. Encourage exponential backoff.
FAQ
What is the difference between token bucket and leaky bucket?
Token bucket allows bursts up to the bucket size, then throttles to the refill rate. Leaky bucket enforces a steady output with no bursts. Token bucket is more forgiving of real traffic.
What HTTP status code means rate limited?
429 Too Many Requests. Pair it with a Retry-After header telling the client when to try again.
Should I rate limit by IP or by user?
By user or API key when you can, since IPs are shared behind NAT and proxies. Many systems apply both layers together.
Does rate limiting stop DDoS attacks?
It helps against abusive clients and accidental floods, but large distributed attacks need dedicated DDoS protection upstream. Rate limiting is one layer, not the whole defense.
Where to go next