429.
Limits are per model, not a single global ceiling. Spreading load across
models also adds headroom.
Handling 429s
When you receive a429, back off and retry with exponential backoff and
jitter. Jitter spreads retries out over time so a fleet of clients doesn’t all
retry in lockstep and stampede the limit again.
1
Catch the 429
Detect the
429 status (or a RateLimitError from your client library).2
Wait, backing off exponentially
Sleep for an interval that doubles each attempt, capped at a ceiling
(e.g. 30s), and add a small random jitter on top.
3
Retry, then give up
Retry up to a fixed number of attempts. If you’re still limited after the
last attempt, surface the error rather than looping forever.
Reducing pressure
If you’re regularly hitting429, reduce the load you put on a model’s limits
rather than just retrying harder.
Batch embeddings
Send an array of inputs in a single embeddings request instead of one
request per input. Fewer requests means less RPM pressure for the same work.
Cap output
Set
max_tokens to what you actually need. Shorter outputs consume less of
the TPM budget.Limit concurrency
Cap how many requests you fire in parallel from a single workspace so you
stay under the RPM limit instead of bursting past it.
Dedicated capacity
For sustained high volume, a dedicated endpoint gives you reserved
throughput instead of sharing a shared model’s limits.
Checking headroom
You don’t have to wait for a429 to know you’re approaching a limit.
Rate-limit headroom, how close your traffic is running to a model’s limits,
is visible in your observability. Each request’s
detail in the request log shows its headroom, so you can watch how much of a
model’s TPM and RPM budget you’re consuming and scale back (or move to a
dedicated endpoint) before you start hitting limits.