Guide
Token bucket, leaky bucket and window rate limits compared
Every public API needs a rate limit, both to protect the service and to share it fairly between clients. The common algorithms sound similar on paper but treat bursts very differently, and the right numbers depend on how your clients actually behave. This simulator runs the four classic algorithms on the same traffic and shows, second by second, which requests get through.
Token bucket
A bucket holds up to a fixed number of tokens and starts full. Each request takes one token, and tokens are added back at a steady rate. A client can therefore send a burst as large as the bucket at once, then continue at the refill rate. This matches how people use APIs, quick bursts followed by pauses, which is why token buckets are the most common choice for public APIs.
Leaky bucket
A leaky bucket is a queue that drains at a constant rate. Requests are accepted while the queue has room and rejected once it is full. The effect is the opposite emphasis from a token bucket: output is smoothed to a steady rate, which protects a downstream system that cannot handle bursts, at the cost of delaying or rejecting clients that send in bursts.
Fixed and sliding windows
A fixed window counts requests per clock interval, such as per second or per minute, and resets the counter at each boundary. It is cheap to implement with a single counter, but a client can send a full window’s worth at the end of one window and again at the start of the next, briefly doubling the allowed rate. A sliding window log avoids that by counting the requests in the last N seconds from each new request, at the cost of storing timestamps.
Burst and sustained rate
Every limit has two numbers worth stating: how many requests a client may send at once, and how many per second it may sustain. For a token bucket those are the bucket size and the refill rate; for a window they are the same number spread over the window. The statistics row shows the sustained rate for the settings you chose.
Traffic patterns
The burst pattern sends three seconds’ worth of requests almost at once, then a slow trickle, which is what a client does after reconnecting. The steady pattern spaces requests evenly. The spiky pattern doubles the rate every third second, like a scheduled job running alongside normal traffic. Change the rate and duration to match your clients.
A worked example
With the defaults, a token bucket of 10 refilled at 2 per second, and the burst pattern at 5 requests per second for 10 seconds, the simulation sends 24 requests. The first 10 of the burst are allowed and the next 5 are rejected with 429, because the bucket is empty and refills only 2 tokens per second. By the time the trickle starts at 3 seconds the bucket has refilled, so all 9 later requests pass: 19 allowed, 5 rejected. A fixed window of 10 per second gives the same totals for this pattern, but the chart shows it rejecting at different moments when you try the spiky pattern.
Headers for clients
Rejected requests should get HTTP 429 Too Many Requests with a Retry-After header. The IETF RateLimit header fields, still a draft, add RateLimit-Policy describing the quota and window and RateLimit with what remains, so clients can slow down before hitting the limit. The panel shows example values for the current settings.
What the simulation leaves out
It models one limiter with idealised timing. Real deployments run limiters on several servers that share counters through Redis or a gateway, with clock differences and synchronisation delays, and usually apply several limits at once. Use the simulation to choose the shape and the numbers, then load-test the real implementation.
Related tools
- Connection Pool Calculator sizes the database behind the API.
- HTTP Status Codes builds the 429 error body.
- Big-O Calculator estimates how request cost grows.
- GraphQL Formatter estimates per-query cost for cost-based limits.
Checked against the current version of the Rate Limit Simulator on .

