Skip to content

Rate Limit Simulator

Watch a token bucket drain, refill and start shedding as you drag the arrival rate past the refill rate.

Requests shed in 60 seconds
38.16%

406 of 1,064 arrivals got a 429. The first one was 14.4s in.

Token bucket level and shed rate over 60 secondstokens in bucket (0–60)requests per second (0–42)0s60s
Top: tokens left in the bucket. Bottom: arrival rate (blue) against the rate being shed (red). The flat line is the refill rate — the only rate you can sustain.
Sustainable rate (the refill rate)
10.00 req/s
Peak arrival rate during the burst
42.00 req/s
Burst the capacity can absorb
1.9 s
Arrivals in the window
1,064
Allowed
658
Shed
406
Tokens left at the end
0.0
What this assumes: arrivals are modelled as a smooth fluid at the rate you set, not as discrete random events. That is the honest simplification here and it errs optimistic: real traffic clumps, so a Poisson arrival process at the same mean rate empties the bucket sooner and sheds more than this chart shows. Tokens refill continuously rather than in a tick every second, the bucket starts full, and one request costs exactly one token — if your limiter charges by tokens-of-text rather than by call, set the arrival rate in those units instead and read the whole chart that way.

The single fact this makes visible is that a bucket has two numbers and only one of them is your rate limit. The refill rate is what you can sustain forever. The capacity is a savings account: it buys you exactly capacity ÷ (arrival − refill) seconds of running over, and then it is gone and you are limited to the refill rate no matter how large the bucket was. Drag the arrival slider slowly through the refill rate and the shed figure goes from zero to zero to zero and then, one step past it, starts climbing — there is no gentle degradation, because the bucket empties at a constant rate once you are over.

That is also why retrying on a 429 without backoff is so destructive. Retries add to the arrival rate, which increases the excess, which drains the remaining capacity faster, which produces more 429s. The model above has no retry term at all — add one and the shed share does not rise linearly, it runs away.

What it leaves out: per-key buckets, so one noisy tenant here is indistinguishable from broad load; queueing, which converts shedding into latency and is usually what you actually want for a background job; and the fact that most published limits are enforced on two axes at once, requests per minute and tokens per minute, so the one that bites is whichever fills first. Run this twice, once in each unit, and size for the tighter answer.

Rate Limit Simulator · Multigrid