Fixed window counters
A car park with five spaces and a barrier. Every thirty seconds the barrier resets and the spaces are free again.
That's a fixed window counter, the simplest rate limiting algorithm there is. Count requests inside a window of fixed length, refuse anything past the limit, and reset the count when the window ends.
Watching one window fill
A limit of five requests per thirty-second window:
| Time | What arrives | Count | Outcome |
|---|---|---|---|
| 0s | 1 request | 1 | Accepted |
| 5s | 2 requests | 3 | Accepted |
| 15s | 2 requests | 5 | Accepted, and the barrier comes down |
| 25s | 1 request | 5 | Rejected, the window is full |
| 30s | Window 2 opens | 0 | The count resets |
The state involved is two values: where you are in the window, and the count so far. Nothing carries over from the window that ended.
That simplicity is the entire appeal. Cheap to store, cheap to check, and hard to get confused about.
That's the algorithm being blunt rather than unfair. It has no notion of nearly, only of inside this window or not.
The boundary burst
Now watch two consecutive windows, with the same limit of five per thirty seconds:
| Time | Window | Requests | Running count |
|---|---|---|---|
| 50s | 2 | 2 | 4 |
| 55s | 2 | 2 | 6, so 5 accepted |
| 60s | 3 opens | 2 | 2 |
Look at the clock rather than the windows. Between 50 and 60 seconds, seven requests were accepted.
The limit was five per thirty seconds, and seven arrived in ten.
Nothing malfunctioned. Requests at the end of window two and the start of window three are in different windows, so neither count ever exceeded five. The algorithm did exactly what it was told.
That's the window boundary issue, and it's the defining weakness of this approach. In the worst case a client sends the full limit immediately before a reset and the full limit immediately after, putting twice the limit through in a moment.
Step back and look at a stretch of clock time crossing the boundary, and the limit was never really enforced there at all.
Try it
An API allows 10 requests per 60-second window, clock-aligned so windows start on the minute.
- A client sends 10 requests at 12:00:59 and 10 more at 12:01:01. How many are accepted, and is the limit broken?
- A client sends all 10 at 12:00:00. What happens to their request at 12:00:30?
- You need to guarantee no client ever gets more than 10 requests in any 60-second stretch. Can a fixed window do it?
Compare your answers
1. All 20 are accepted, and no rule was broken. The first ten fall in the 12:00 window and the second ten in 12:01, so neither count passed 10.
Twenty requests arrived in two seconds. That's the boundary burst, and it took nothing cleverer than noticing when the minute turns.
2. Rejected. The window is full and has thirty seconds left to run. The service is completely idle and the client still waits, which is the drought that comes with the burst.
3. No. Not with a fixed window, at any limit. Any stretch of clock that crosses a boundary can carry up to twice the limit, and that's a property of dividing time into fixed blocks rather than a tuning problem.
Getting that guarantee means measuring against a window that moves with the request instead of a block on a calendar, which is the next chapter.
Where this goes next
Fixed windows are cheap, simple, and wrong by up to a factor of two at the boundary. Whether that matters depends on what the endpoint does.
Before fixing it, it's worth building one. Building a rate limiter turns this algorithm into working Express middleware, with the headers a client needs to behave well.

