429 Too Many Requests: What It Means, When to Retry (2026)
A 429 is one status code for 5 different problems. Read retry-after first, back off 1s/2s/4s with jitter, and skip the retry entirely on billing 429s.
TL;DR
Status code: HTTP 429 (Too Many Requests)
Anthropic: error.type = rate_limit_error, plus a retry-after header
OpenAI: rate-limit 429 and spend/credit 429 share the code; read error.code
Google Gemini: 429 RESOURCE_EXHAUSTED, no retry hint documented
OpenRouter: 429 raised by OpenRouter, or relayed from the upstream provider
First thing to do: read retry-after, wait that long, retry once
No header: back off 1s, 2s, 4s with jitter, cap at 5 attempts
Never retry: credit/spend-cap 429s, they do not clear on their own
The status code tells you almost nothing on its own. The error body and the response headers tell you which of five different problems you have, and two of the five are not fixed by waiting.
What Does “429 Too Many Requests” Mean?
It means your credentials were accepted and the request was refused anyway, because your account asked for more volume than it is allowed right now. The wording differs by vendor (“Rate limit reached for requests”, “rate limit exceeded”, RESOURCE_EXHAUSTED), the status code does not.
Three things a 429 is not:
- An auth failure. A bad or revoked key is a 401, and a key without access to the resource is a 403.
- An outage. Anthropic uses 529
overloaded_errorfor “the API is temporarily overloaded” across all users, separate from your own limits. - Necessarily about your traffic. On a router, the 429 can be the upstream provider’s, relayed to you.
The window is usually a minute, but it is not a clock minute. Anthropic documents its limiter as a token bucket: “your capacity is continuously replenished up to your maximum limit, rather than being reset at fixed intervals.”
Is a Rate Limit Exceeded Error My Fault or the Provider’s?
Neither, most of the time. It is a policy decision about your account, and there are five distinct policies that produce the same status code.
| What you actually hit | How it identifies itself | Does waiting fix it? |
|---|---|---|
| Per-minute request or token cap | Anthropic rate_limit_error + retry-after; OpenAI “Rate limit reached for requests” | Yes, after the documented wait |
| Spend or credit cap | OpenAI error.code of credit_balance_exhausted, organization_spend_limit_exceeded, project_spend_limit_exceeded, organization_usage_limit_exceeded | No. Retrying burns quota on nothing |
| Acceleration limit (traffic ramped too fast) | Anthropic 429 on a sharp usage increase, under your nominal limits | Yes, but the fix is a gradual ramp |
| Free-tier daily cap | OpenRouter :free models: 20 requests/minute, 50 requests/day under 10 credits purchased, 1,000/day at 10+ | No, not until the day rolls over |
| Upstream provider capacity | OpenRouter error.metadata.provider_code carrying the provider’s original code | Retrying the same route makes it worse. Fail over |
OpenAI states the split plainly: Retry-After “does not mean that quota, billing, or other errors that require user action can be resolved by retrying.” A retry loop that treats every 429 the same will sit there hammering an exhausted credit balance until your alerting notices.
The last row is the one people misdiagnose most often. When a launch-constrained model returns 429 regardless of your tier, no amount of backoff on that route helps, which is exactly the shape of the OpenRouter Kimi K3 429 problem.
Which Header Tells You When to Retry?
Read retry-after. It is the only value the server is telling you directly, and every other header is context. The rest of the header set differs by vendor, including the format of the reset value.
| Vendor | Headers on the response | Reset format |
|---|---|---|
| Anthropic | retry-after, anthropic-ratelimit-requests-{limit,remaining,reset}, anthropic-ratelimit-input-tokens-*, anthropic-ratelimit-output-tokens-*, anthropic-ratelimit-tokens-* | RFC 3339 timestamp |
| OpenAI | Retry-After, x-ratelimit-{limit,remaining,reset}-requests, x-ratelimit-{limit,remaining,reset}-tokens, plus project-scoped *-project-tokens | Duration string (1s, 6m0s) |
| Google Gemini | Not documented for the rate-limit path; the docs prescribe exponential backoff instead | n/a |
| OpenRouter | X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset when OpenRouter itself throttles; Retry-After when provider-side limits force retries | Not returned on successful responses |
Two traps in that table:
- The reset value is not the same type across vendors. Anthropic returns a timestamp you compare against the clock. OpenAI returns a Go-style duration you parse as an interval. Code that assumes one shape silently produces garbage against the other.
- Anthropic rounds remaining token counts to the nearest thousand, so treating
anthropic-ratelimit-input-tokens-remainingas exact will overshoot on small requests.
Header presence is also not guaranteed, which matters most on a gateway. Testing four models through one OpenAI-compatible endpoint on 2026-08-10, two routes returned a full x-ratelimit-limit-requests / -limit-tokens / -remaining-* / -reset-* set (plus a non-standard x-ratelimit-renewalperiod-requests: 60), and two returned no rate-limit headers at all. The header set belongs to whoever serves the model, not to the endpoint you called. Write the parser so a missing header degrades to backoff instead of throwing.
How Long Should You Wait After a 429?
As long as retry-after says, and if there is no header, 1s, 2s, 4s with jitter, capped at five attempts. Fixed sleeps are the wrong answer, because every parallel worker wakes at the same instant and re-trips the same limit.
| Attempt | Base delay | With full jitter, actually sleep |
|---|---|---|
| 1 | 1s | 0 to 1s |
| 2 | 2s | 0 to 2s |
| 3 | 4s | 0 to 4s |
| 4 | 8s | 0 to 8s |
| 5 | 16s | 0 to 16s |
The jitter is the part people skip, and it is the part that matters when 20 workers hit the wall together.
import random, time
from openai import OpenAI, RateLimitError
client = OpenAI(base_url="https://api.ofox.run/v1")
def call_with_backoff(**kwargs):
for attempt in range(5):
try:
return client.chat.completions.create(**kwargs)
except RateLimitError as e:
# the SDK unwraps the envelope, so e.body is the inner "error" object
code = e.body.get("code") if isinstance(e.body, dict) else None
if code in {"credit_balance_exhausted", "organization_spend_limit_exceeded"}:
raise # a spend cap does not clear by waiting
retry_after = e.response.headers.get("retry-after")
delay = float(retry_after) if retry_after else random.uniform(0, 2 ** attempt)
time.sleep(delay)
raise RuntimeError("still rate limited after 5 attempts")
Before you write that loop, check whether your SDK already did it. Reading the installed openai 2.53.0 client: DEFAULT_MAX_RETRIES is 2, the retry path parses retry-after-ms first and then retry-after (seconds, or an HTTP date), honors a server-directed delay up to 120 seconds, and refuses to retry at all when the server asks for longer than that. With no header it backs off 0.5 * 2^n, capped at 8 seconds, times a jitter factor between 0.75 and 1.0. Anthropic’s SDKs also retry transient failures twice by default and honor retry-after. So on defaults, a 429 that surfaces in your code already failed three times with only about half a second and then one second between attempts, which is nowhere near a minute-long window. Raise max_retries or own the loop; do not stack a second retry layer on the first.
What Do RPM, TPM, ITPM, and OTPM Actually Count?
Different vendors meter different things, and the unit decides which knob helps.
- RPM counts calls, not size. If you keep tripping it, put more work in each call.
- TPM is one combined budget for input and output. OpenAI layers RPD, TPD, and IPM (images per minute) on top for some models.
- ITPM and OTPM are Anthropic’s split of that budget, enforced per model class, so a long-context workload and a long-output workload hit different walls.
- Cached reads are the interesting exception. On most Claude models
cache_read_input_tokensdo not count toward ITPM, whilecache_creation_input_tokensdo. Anthropic’s own example: a 2,000,000 ITPM limit at an 80% cache hit rate processes about 10,000,000 total input tokens per minute. max_tokensdoes not factor into OTPM, which is evaluated on tokens actually produced. A generous ceiling costs you nothing in rate-limit terms.- Concurrency limits are a different animal. Some providers cap in-flight requests rather than per-minute rate, and the five-vendor rate-limit comparison has the per-tier numbers.
Why Do I Get a 429 When I’m Barely Sending Traffic?
Because per-minute limits are rarely enforced per minute, and the bucket is rarely yours alone. The usual suspects:
- Sub-minute enforcement. Anthropic’s docs are explicit: “a rate of 60 requests per minute (RPM) might be enforced as 1 request per second. Short bursts of requests can exceed the limit and trigger rate limit errors.”
- One bucket for the whole org. Limits sit at the organization level, not per key, so every service, notebook, and CI job draws from the same pool unless you set per-workspace limits.
- Fan-out. Parallel agents multiply concurrent requests and carry full context in each one, so ITPM goes first.
- Acceleration limits. A sharp increase in usage can trip a 429 while you are still under your stated limit.
- Free-tier daily caps. A 50-request daily allowance is gone after one afternoon of debugging.
- A billing 429 in disguise. Zero traffic plus a 429 usually means a spend cap or an exhausted balance, not throughput.
If you are seeing this inside a coding agent rather than your own code, the mechanics are the same but the knobs are different, and the Claude Code rate limit walkthrough covers the concurrency settings.
Is 429 the Same as 529 or RESOURCE_EXHAUSTED?
No. 429 is about your account, 529 and 503 are about the provider, and RESOURCE_EXHAUSTED is Google’s name for 429.
| Code | Vendor wording | Whose problem | What to do |
|---|---|---|---|
| 429 | rate_limit_error (Anthropic), rate limit reached (OpenAI) | Your account’s limits or billing | Read the body, then wait or fix billing |
429 RESOURCE_EXHAUSTED | Google Gemini | Your quota (RPM, TPM, RPD) | Exponential backoff, or request quota |
| 529 | overloaded_error (Anthropic) | Provider capacity, everyone | Back off, or fail over to another model |
| 503 | Service unavailable / UNAVAILABLE | Provider capacity | Back off and retry |
| 500 | api_error | Provider bug or fault | Retry with backoff, then report with the request ID |
The distinction is worth wiring into your logs. A dashboard that counts “429 + 529” as one number cannot tell you whether to buy a higher tier or add a fallback route. If you want the deeper version of the capacity case, see the Claude API 529 overloaded guide.
How Do You Stop Getting 429s?
In rough order of effort per unit of relief:
- Honor
retry-afterand add jitter when it is absent. Free, and it fixes the self-inflicted portion. - Cap client-side concurrency. A semaphore around your worker pool is a more reliable limiter than any retry policy, because it prevents the burst instead of reacting to it.
- Cache your prefixes. On Claude models this buys real ITPM headroom, not only a cheaper bill, and the prompt caching cost math shows where the break-even sits.
- Move non-urgent work to a batch endpoint. Batch APIs carry separate limits and are usually half price.
- Fail over instead of retrying harder. When the 429 is upstream capacity, a second model on the same request shape recovers the call in one hop. That is the practical argument for one endpoint with several models behind it: ofox is OpenAI-compatible, so the fallback is a model-string change rather than a second integration.
- Ask for a raise. Anthropic has a “Request rate limit increase” flow in the Console, and OpenAI moves accounts up tiers by cumulative spend. Neither is instant, so this is the plan for next month, not this afternoon.
Two things not to do: do not shard one workload across multiple API keys in the same organization (the limit is org-level, so nothing changes), and do not lower max_tokens hoping to relieve an output limit unless you are actually generating that many tokens.
Sources Checked for This Refresh
- https://platform.claude.com/docs/en/api/rate-limits
- https://platform.claude.com/docs/en/api/errors
- https://developers.openai.com/api/docs/guides/rate-limits
- https://developers.openai.com/api/docs/guides/error-codes
- https://ai.google.dev/gemini-api/docs/rate-limits
- https://ai.google.dev/gemini-api/docs/troubleshooting
https://openrouter.ai/docs/api-reference/limits
Frequently Asked Questions
- Does a 429 mean my API key is banned or invalid?
- No. An invalid or revoked key returns 401 (authentication error), and a key without access to a resource returns 403. A 429 means the key authenticated fine and the request was refused on volume grounds, so the same key will work again once the window refills or the billing problem is fixed.
- Do rate limits reset at the top of every minute?
- Not on the Claude API. Anthropic documents a token bucket: capacity is continuously replenished up to your maximum rather than reset at fixed intervals. That is why a burst can trip a 429 seconds after a previous burst succeeded, and why the reset headers give you a timestamp instead of a fixed clock boundary.
- Does prompt caching raise my rate limit?
- On most Claude models, effectively yes for input. Anthropic documents that cache_read_input_tokens do not count toward ITPM (Claude Haiku 3.5 is the exception and does count them), while cache_creation_input_tokens do count. Vendors that enforce one combined TPM number usually count all input tokens, cached or not, so caching there cuts the bill without buying rate-limit headroom.
- Should I retry a 429 immediately if there is no retry-after header?
- No. Retrying immediately is how a short throttle becomes a sustained one, because every parallel worker retries at the same instant. With no header, back off exponentially with jitter and cap the number of attempts. If the error body points at a spend cap or an exhausted credit balance, do not retry at all.


