Fixed window, sliding window, token bucket and leaky bucket
coreintermediateA rate limiter decides, for each incoming request, whether to allow it or reject it based on how many requests the same caller has already made recently. The four standard algorithms differ in how they track "recently" and how they handle bursts: fixed window counts requests in a clock-aligned bucket and resets abruptly, sliding window smooths that count across a moving time range, token bucket allows controlled bursts by spending saved-up tokens, and leaky bucket forces a constant output rate regardless of how bursty the input is.
Think of it as
Think of four different door policies for a club with a "50 people per hour" rule. Fixed window is a bouncer who resets his tally sheet to zero the moment the clock hits the new hour — anyone waiting just outside can rush in right at the reset, doubling up on the boundary. Sliding window is a bouncer who always looks back exactly 60 minutes from right now, so there is no reset moment to exploit. Token bucket is a bouncer handing out a fixed number of tickets per minute that pile up if unused, so a quiet hour lets a sudden crowd burst in all at once using saved tickets. Leaky bucket is a single-file turnstile — people can arrive in any clump, but they are let through the door at one constant, unhurried pace no matter how the crowd bunches up outside.
What we're doing: Show the classic fixed-window boundary-burst problem concretely: a limit of 100 requests/minute lets through nearly 200 in a short span straddling the window edge.
- 5
- All 100 requests in the last 30 seconds of window A are allowed — window A's counter is exactly at the limit, not over it.
- 7
- The moment the clock ticks into window B, the counter resets to 0, so the next 100 requests are allowed too, even though they arrive seconds after the first 100.
- 10
- The 60-second sliding span 12:00:30-12:01:29 saw 200 requests — double the stated limit — purely because it straddles the fixed-window reset point.
Why this works: This is the concrete reason production systems reach for sliding window, token bucket or leaky bucket instead of fixed window when a hard burst cap actually matters — fixed window's simplicity trades away a real guarantee at the boundary, not just a theoretical edge case.
Assuming a fixed-window limiter caps the true worst-case burst at the stated limit
Wrong
Better
What you see: A downstream system sized for "100 requests/minute" gets overwhelmed by traffic that a fixed-window limiter reported as fully compliant — the spike lands across a window boundary and each half looks fine to its own counter.
Why: A fixed window only bounds the count within each clock-aligned interval independently; it makes no promise about any other 60-second span, including ones that straddle two windows — that gap is exactly where up to double the stated limit can get through.
- Fixed window — resets abruptly at the boundary
- Sliding window — a continuously moving range
- Token bucket — allows a burst up to bucket size
- Leaky bucket — constant, fixed drain rate
The four algorithms compared
Remember: Fixed window: simple, but up to ~2x the limit can leak through a window boundary. Sliding window: closes that gap, costs more state. Token bucket: allows bursts up to bucket size after idle time. Leaky bucket: forces a constant output rate, queuing or dropping the rest.
See also: distributed rate limiting · rate limit scope · redis use cases

