Rate Limiter Config Generator
Your throughput and your provider's two limits in; token-bucket parameters, the limit that actually binds, and the queue wait at your utilisation out.
Bound by the token-per-minute limit, minus 20.0% headroom. You asked for 450, which is 84.4% of it.
- Tokens per request
- 1,500
- Requests per minute the token limit allows
- 667
- Requests per minute the request limit allows
- 1,000
- Which one binds
- the token-per-minute limit
- Usable after headroom
- 533 req / min
- Per instance
- 133 req / min
- Bucket refill rate
- 2.222 permits / s
- Bucket capacity
- 15 permits
- Time to refill a drained bucket
- 6.75 s
- Utilisation at your target
- 84.4%
- Mean queue wait at that utilisation
- ≈ 304 ms
- Tokens per minute you would consume
- 675,000
- Token limit used
- 67.5%
- You are running at 84.4% of the usable rate. Queue wait rises as 1/(1-ρ), so the last 10% of capacity costs more waiting than the first 80% put together — the mean wait above is roughly 304 ms, and it doubles again between 90% and 95%.
Two limits apply to almost every model API at once, and people configure for the wrong one. A request-per-minute limit is easy to think about and is usually not the one that stops you: at a couple of thousand tokens a request, a token-per-minute limit runs out first, and it runs out sooner every time someone lengthens the system prompt. The number that matters is the token limit divided by your tokens per request, and it is the first row of the table above.
Why a bucket rather than a sleep
A token bucket gives you two knobs that map onto what you actually want: a sustained rate, and a burst you can absorb without waiting. Sleeping a fixed interval between calls gives you the rate and throws away the burst — which is exactly the behaviour that makes a batch job take four times longer than it needs to when the quota was sitting unused for the previous minute.
Utilisation is not linear, and neither are your instances
Running at 95% of a limit does not cost 19% more waiting than running at 80%; queueing goes as 1/(1−ρ), so it costs several times more. And a per-process bucket cannot lend a permit to a busier process: split a quota four ways and a spike that lands on one pod is throttled while three buckets sit full. Both effects are in the numbers above so the choice between a local bucket and a shared one is made on arithmetic rather than on taste.