Rate Limit Designer
A rate limiter designer. Enter the sustained rate you want to allow and how big a burst to tolerate, and get concrete token-bucket parameters (refill rate and capacity), the effective peak burst, and how the choice compares to fixed-window and sliding-window approaches — including the boundary-burst pitfall of fixed windows.
Algorithm comparison
- Token bucket (recommended)
refill 1.67 / sec, capacity 150Smooth average rate with a controlled burst. Cheap state (count + timestamp).
- Fixed window
100 per 60s, hard resetBoundary bug: up to 200 requests across a reset edge. Simplest, but spiky.
- Sliding window
100 over a moving 60sNo boundary spike, most precise — but more state (timestamps / weighted counters).
A rate limiter is a policy, and the token bucket is the cleanest way to express it. Picture a bucket that refills at a steady rate and holds a maximum number of tokens; every request spends one, and an empty bucket means the request is throttled. That gives you two dials that map directly onto what you want: the refill rate is your allowed sustained throughput, and the capacity is how big a burst you tolerate after a quiet period. This tool turns your target rate and burst into exactly those two numbers.
The reason to prefer it becomes obvious when you look at the naive alternative. A fixed window — say 100 requests per minute that resets on the minute — has a boundary hole: a client fires 100 requests at 11:00:59 and 100 more at 11:01:00, sneaking 200 through in two seconds while never violating the per-minute count. A token bucket has no reset edge to exploit; it enforces the average continuously and only ever lets through the burst you explicitly sized for.
A sliding window also closes the boundary hole by counting over a moving interval, and it is more precise about the exact rate — but it carries more state (timestamps or weighted counters) than the token bucket’s single count-plus-timestamp, which is why the bucket wins on cost and ubiquity. The last decision is where the state lives: a per-server bucket lets clients cheat by fanning out across servers, so a true global limit keeps its counter in a shared store like Redis that every limiter consults atomically. Same algorithm, just placed where the whole cluster can see it.
How it works
- Refill rate = sustained rate; capacity = burst allowance.
- Shows the effective peak burst you are permitting.
- Compares token bucket vs fixed vs sliding window.
- Flags the fixed-window boundary double-burst pitfall.
Frequently asked questions
How do token-bucket parameters map to my rate?
A token bucket has two knobs: the refill rate (tokens added per second) sets your sustained throughput, and the bucket capacity sets your maximum burst. Each request costs one token; if the bucket is empty, the request is limited. So refill rate = your allowed sustained rate, and capacity = how many requests you allow to arrive back-to-back after an idle period. This tool converts your target rate and burst allowance into those two numbers.
Why is a token bucket usually preferred over a fixed window?
A fixed window (e.g. 100 requests per minute, reset on the minute) has a notorious boundary problem: a client can send 100 requests at 11:00:59 and another 100 at 11:01:00, landing 200 in two seconds while never breaking the per-minute rule. A token bucket smooths this out — it enforces the average rate continuously while still allowing a controlled burst up to the bucket size, with no reset-boundary spike.
What is the difference from a sliding window?
A sliding-window limiter counts requests over a moving time window, which fixes the fixed-window boundary spike and enforces the limit smoothly, but it needs more state (timestamps or weighted counters) to track the window. A token bucket achieves a similar smoothing with just a token count and a last-refill timestamp, which is cheaper and why it is so widely used. Sliding-window is more precise about the exact rate; token bucket is simpler and allows explicit bursts.
How do I rate-limit across many servers?
A per-server in-memory bucket lets a client exceed the global limit by spreading requests across servers. For a global limit you keep the counter in a shared store (commonly Redis) that all servers consult atomically, trading a little latency for a correct cluster-wide limit. Alternatively, divide the limit across servers if traffic is evenly load-balanced. The algorithm is the same; the state just has to live where every limiter can see it.