The Burst at Window Edge
Fixed window counters reset at exact time boundaries. If a burst arrives right at the reset, it can get through even if the previous window was full. This can double your expected rate for a brief moment.
Developer Utility
Model token bucket, fixed window, and sliding window algorithms. Fire requests at different speeds. Watch what gets through and what gets blocked. All in your browser.
These examples show common situations engineers run into. Load one to see what happens.
Fixed window counters reset at exact time boundaries. If a burst arrives right at the reset, it can get through even if the previous window was full. This can double your expected rate for a brief moment.
Token bucket refills slowly. A steady trickle of requests passes fine, but a sudden flood empties the bucket and everything after gets rejected until tokens refill. This is the most common surprise in production.
Sliding window tracks each request timestamp. It avoids the boundary problem of fixed window but uses more memory. Here you see it smoothly rejecting requests that exceed the rolling limit.
A client retries aggressively after being throttled. The retries count against the limit, causing more rejections, causing more retries. This feedback loop can make a small spike look like a DDoS.
Setting a low request count without accounting for natural bursts in user behavior. Users click fast, scripts retry, and batch jobs fire many requests at once. If your limit is too tight, real users get blocked. Start with a higher burst allowance and tighten based on real traffic data.
A 1-second window with 100 requests allows bursts of 100 in a single second. A 60-second window with 100 requests allows only ~1.67 requests per second on average. The same number feels very different depending on the window. Always check both values together.
This simulator models a single server. In production, you likely have multiple servers behind a load balancer. Each server may have its own counter, or you may use a shared store like Redis. Clock skew between servers can cause counters to drift. Test with your actual infrastructure.
When you reject a request, the client needs to know when to try again. Without a Retry-After header, clients guess. Some back off too slowly and keep getting rejected. Some back off too fast and waste capacity. Always include timing hints in 429 responses.
| Algorithm | Burst Handling | Memory | Boundary Issue | Best For |
|---|---|---|---|---|
| Token Bucket | Controlled by bucket size | Low | None | General APIs |
| Fixed Window | Full window at reset | Very Low | Double traffic at edges | Simple limits |
| Sliding Window | Smooth | Higher (timestamps) | None | Fair rate limiting |