How should a high-throughput service absorb provider 429 responses?
Your service regularly hits an LLM provider's rate limit and receives 429s. Describe how to absorb them well, and why blind immediate retries make it worse.
Shape demand to the quota: honor the Retry-After header, smooth your send rate with a client-side token bucket, back off with jitter, and shed low-priority traffic near the cap — never retry a 429 immediately.
Imagine a popular ride at a theme park with a 'one group every 30 seconds' rule. If you shove your whole crowd at the gate the instant you're turned away, you just jam it harder and everyone's turned away again. The smart move is to let people through in a steady trickle that matches the gate's pace, and when the operator says 'wait 30 seconds', you actually wait. If the line is too long, you send the VIPs first and ask the casual visitors to come back later. That steady, signal-following pacing is exactly how a service should handle a provider that says 'too many requests'.
Detailed answer & concept explanation~6 min readEverything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example.
Everything important, quickly.
Spend 6-8 minutes on proactive shaping versus reactive retries and the distributed-limiter trap, the two ideas that separate a senior answer from a junior one here.
# Honor Retry-After, fall back to jittered backoff
import random, time
def on_429(resp, attempt, base=0.5):
ra = resp.headers.get("Retry-After")
if ra is not None:
wait = float(ra) # provider told us exactly
else:
wait = base * 2 ** attempt # exponential backoff
wait *= random.random() # full jitter, de-sync clients
time.sleep(wait)
# ...then retry, but only if a token-bucket admit() also allows it,
# so we stay under the quota instead of bursting back into it.Real products, models, and research that use this idea.
- OpenAI and Anthropic APIs return a Retry-After header on 429s plus rate-limit headers showing remaining quota.
- LLM gateways like LiteLLM and Portkey enforce client-side rate limits and queue requests to stay under provider caps.
- Distributed token-bucket limiters backed by Redis are the standard way multi-instance services share a provider quota.
- AWS SDKs use full-jitter exponential backoff as the reference pattern for absorbing throttling responses.
What an interviewer would ask next. Try answering before peeking at the approach.
QHow do you size and share a token bucket across many service instances behind a load balancer?
QThe provider rate-limits on tokens per minute, not requests per minute. How does that change your limiter?
Don't say thisRed flags and common mistakes that signal junior thinking. Click to expand.
Red flags and common mistakes that signal junior thinking. Click to expand.
Retrying a 429 immediately in a tight loop, which is just another request against an already-exceeded limit and synchronizes every client into a retry storm.
The night-before-the-interview bullets. Scan these on the way to the call.
Primary sources. Skim if you want the original framing.
Same topic, related formats. Practice these next.