Rate limits
How throttling works, what a 429 means here, and how to build a client that does not trigger one.
Limits keep shared upstream capacity fair. They apply per account, not per key, so adding keys does not raise your ceiling.
What is limited
| Dimension | Behaviour |
|---|---|
| Concurrent requests | In-flight requests per account. The usual cause of a 429. |
| Requests per minute | Sustained call rate. |
| Tokens per minute | Combined input and output throughput. |
Unlimited plans apply fair-use limits rather than a credit balance — they remove the per-token charge, not the concurrency ceiling.
Handling 429 properly
- Back off exponentially with jitter — 1s, 2s, 4s, 8s, each plus or minus a random fraction.
- Cap concurrency client-side with a semaphore instead of firing everything and retrying the rejects.
- Queue batch work rather than parallelising it maximally; throughput is bounded by tokens per minute, not by how many sockets you open.
- Treat
529differently from429— that is upstream capacity, not you, and usually clears within seconds.
import asyncio
sem = asyncio.Semaphore(8) class=class="s">"c"># ceiling on concurrency, tune to your plan
async def ask(client, body):
async with sem:
return await client.post(class="s">"/v1/messages", json=body)
Agentic tools such as Claude Code fan out aggressively by design. If you see 429s during heavy agent use, lower the tool's parallelism before raising your plan.
Reducing pressure instead of retrying
- Route cheap work to
claude-haiku-4-5— smaller models finish sooner and hold a slot for less time. - Turn on prompt caching: cached prefixes cut input tokens and therefore token-per-minute pressure.
- Trim conversation history; see Context management.
- Batch offline work into off-peak windows.