Claude API Error 429 Rate Limit Fix: Complete Guide
Why You're Seeing Error 429
A 429 "Too Many Requests" error from the Claude API means you've exceeded one of Anthropic's rate limits — either requests per minute (RPM), tokens per minute (TPM), or in some cases a daily spend cap tied to your usage tier. The fix depends on which limit you're hitting, but in almost every case it comes down to three things: slow down your request rate, retry with backoff, or increase your allocated limits.
This guide walks through exactly how to diagnose which limit you're bumping into, how to handle 429s gracefully in code so your app doesn't crash or hang, and what longer-term options exist if your usage keeps growing past what your account tier allows.
Step 1: Read the Response Headers
Before writing any retry logic, check the response headers Anthropic sends back with a 429. They tell you exactly what limit you hit and when it resets:
curl -i https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model":"claude-opus-4-20250514","max_tokens":1024,"messages":[{"role":"user","content":"hi"}]}'
Look for headers like:
anthropic-ratelimit-requests-remaininganthropic-ratelimit-tokens-remainingretry-after
If retry-after is present, that's the number of seconds you should wait before trying again. Don't guess — use that value.
Step 2: Implement Exponential Backoff with Jitter
The single most important fix for 429 errors is retry logic with exponential backoff. Hammering the API immediately after a 429 just triggers more 429s and can get you temporarily throttled harder.
async function callClaudeWithRetry(payload, maxRetries = 5) {
let attempt = 0;
while (attempt < maxRetries) {
const res = await fetch("https://api.anthropic.com/v1/messages", {
method: "POST",
headers: {
"x-api-key": process.env.ANTHROPIC_API_KEY,
"anthropic-version": "2023-06-01",
"content-type": "application/json"
},
body: JSON.stringify(payload)
});
if (res.status !== 429) return res.json();
const retryAfter = res.headers.get("retry-after");
const waitMs = retryAfter
? Number(retryAfter) * 1000
: Math.min(2 ** attempt * 1000, 30000) + Math.random() * 500;
await new Promise(r => setTimeout(r, waitMs));
attempt++;
}
throw new Error("Rate limit retries exhausted");
}
The key details:
- Respect
retry-afterif present — it's more accurate than guessing. - Cap the maximum delay so a bad loop doesn't hang your app for minutes.
- Add jitter (small random offset) so multiple concurrent requests don't retry in lockstep and cause another burst.
Step 3: Queue and Throttle Requests Client-Side
If you're sending lots of requests in parallel (batch jobs, bulk processing, high-traffic endpoints), backoff alone isn't enough — you need to control concurrency before hitting the API.
class RequestQueue {
constructor(rps = 2) {
this.interval = 1000 / rps;
this.queue = [];
this.running = false;
}
add(fn) {
return new Promise((resolve, reject) => {
this.queue.push({ fn, resolve, reject });
this.run();
});
}
async run() {
if (this.running) return;
this.running = true;
while (this.queue.length) {
const { fn, resolve, reject } = this.queue.shift();
try {
resolve(await fn());
} catch (e) {
reject(e);
}
await new Promise(r => setTimeout(r, this.interval));
}
this.running = false;
}
}
This caps your outbound request rate to something safely under your limit, rather than firing everything at once and hoping backoff cleans it up afterward.
Step 4: Check Which Limit You're Actually Hitting
429s aren't all the same. Common causes:
- TPM limit — you're sending large prompts or requesting long completions faster than your token budget allows. Reducing
max_tokensor batching fewer requests per minute helps. - RPM limit — lots of small, frequent requests. Consolidate calls where possible (e.g., batch multiple questions into one prompt instead of five separate requests).
- Concurrent connection limits — if you're streaming many responses at once, open connections count against you too.
- Account tier caps — new or low-spend accounts get lower limits by default. Anthropic raises these automatically as usage and billing history grow, or you can request a limit increase through their console.
Step 5: Reduce Token Usage to Buy Headroom
Since TPM limits count both input and output tokens, trimming unnecessary context helps you stay under the ceiling without needing a limit increase:
- Strip unused system prompt boilerplate
- Truncate or summarize long conversation history instead of sending the full thread every time
- Lower
max_tokensto only what the task actually needs - Cache repeated system prompts/tools where your workflow allows it
When to Consider an API Gateway Instead
If you're building a product on top of Claude — not just scripting one-off calls — manually juggling retry logic, queues, and per-key rate limit tracking across a team adds up fast. This is where a layer like SubToAPI becomes useful: it exposes your Claude access as a standard HTTPS API with its own sub_live_... keys, so you get usage metadata, streaming, and tool use without hand-rolling rate-limit bookkeeping for every service that calls Claude.
Instead of every microservice independently managing retries and RPM math, you route calls through one place and manage limits and visibility centrally. Check the pricing page for plan details, or jump into the quickstart to see how requests are structured — it mirrors the native Messages and streaming APIs, so migrating existing retry logic is mostly a base-URL change.
Quick Checklist
- Read
retry-afterand rate limit headers on every 429 - Implement exponential backoff with jitter, not fixed-delay retries
- Throttle concurrent requests client-side instead of firing everything at once
- Identify whether it's RPM, TPM, or concurrency causing the 429
- Trim token usage where possible before requesting a limit increase
- Centralize API access with something like SubToAPI if multiple services call Claude independently
Questions
Does retrying immediately after a 429 ever work? Rarely. Immediate retries usually hit the same limit window and trigger another 429. Always wait at least the retry-after value, or use exponential backoff if that header isn't present.
Will Anthropic automatically raise my rate limits? Limits typically increase as your account's usage and billing history grow, but you can also request manual increases through Anthropic's console if you have a specific scaling need.
Can batching requests help avoid 429s? Yes. Combining multiple small prompts into a single request reduces RPM pressure, though it can increase token usage per call, so balance against your TPM limit too.