HTTP status 429 ("Too Many Requests") means your organization has exceeded a rate limit — a cap on requests or tokens per time window. On the Claude API these limits vary by usage tier: new organizations start on the Start tier, Build and Scale raise the ceilings, and going beyond Scale means contacting sales. The same tiering logic applies on Claude Platform on AWS, where rate limits and quotas are managed by Anthropic rather than AWS quota systems — organizations start on the Start tier, do not move up automatically, and contact Anthropic to raise limits. So the first response to persistent 429s is organizational, not technical: confirm which tier you're on and whether it matches your traffic.
The client-side contract
When a 429 does arrive, well-behaved SDK code follows three rules. First, treat it as retryable but not immediately retryable — the whole point is that the current window is full. Second, honor any server-provided wait signal: where a response carries a retry-after header or equivalent rate-limit metadata, use that value as the floor for your wait rather than substituting your own guess. Third, back off exponentially with jitter when no explicit signal is available. In Python, the SDK surfaces HTTP failures as typed exceptions, so the skeleton looks like this:
import random, time
from anthropic import Anthropic
client = Anthropic()
def call_with_backoff(request, max_attempts=5):
for attempt in range(max_attempts):
try:
return client.messages.create(**request)
except Exception as err:
status = getattr(err, "status_code", None)
if status != 429 or attempt == max_attempts - 1:
raise
# Exponential backoff with full jitter
time.sleep(random.uniform(0, min(60, 2 ** attempt)))
The official SDKs also retry certain failures automatically — check the README of your language's SDK for the current defaults before layering your own loop on top, so exactly one layer owns the retry decision.
Why jitter is not optional
Exponential backoff alone has a failure mode: determinism. If fifty workers hit the limit in the same second and all wait exactly two seconds, then four, then eight, they re-arrive as a synchronized wave each round — the "thundering herd." The limit that bounced them the first time bounces the whole herd again. Adding randomness (in the sketch above, a uniform draw between zero and the backoff ceiling) decorrelates the fleet so retries trickle back rather than stampede. For high-concurrency systems, go one step further and put a shared, client-side limiter in front of the API — a token bucket or a bounded worker pool — so the fleet stops generating more requests than its known budget rather than discovering the limit via 429s.
Design so 429s are rare, then harmless
Backoff is the safety net, not the strategy. Three structural moves reduce how often you need it. Right-size the model: routing high-volume, simple traffic to a cheaper, faster model keeps your heavyweight-model budget for the calls that need it — and Haiku 4.5 has its own rate-limit pool, separate from older Haiku generations. Smooth the demand: queue non-urgent work and drain it at a controlled rate instead of letting user spikes pass straight through to the API; for genuinely offline volume, batch mechanisms (Anthropic's Message Batches API where available, or the cloud-native batch offerings on Bedrock and Vertex AI) move the work out of your synchronous budget entirely. Isolate workloads: on the Claude API and Claude Platform on AWS, usage and quotas roll up per workspace, so separating production traffic from experiments means a runaway notebook can't starve customers.
Finally, make 429s observable. Count them per workload and alert on the trend, not the single event: a slow rise is your early warning to request a higher tier before customers feel it.
Where to go next
This article is one of a trio with configuring retries and timeout tuning. For reading rate-limit response headers in detail, see the rate-limit headers article; for the platform-specific view, see error codes on Claude Platform on AWS.