Rate Limit Simulator
Watch a token bucket drain, refill and start shedding as you drag the arrival rate past the refill rate.
406 of 1,064 arrivals got a 429. The first one was 14.4s in.
- 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
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.