Skip to main content
429Retryable

Anthropic 429 Rate Limited

You exceeded requests-per-minute, input-tokens-per-minute or output-tokens-per-minute for your tier. The retry-after header says when to come back.

Most likely causes

  1. 1.Concurrent agents bursting past RPM on a low tier
  2. 2.ITPM exhausted by large contexts even at modest request rates
  3. 3.Retry storm: failed calls retried without backoff amplify the limit hit

Fix checklist

  • Honor the retry-after response header — it is exact, not a hint
  • Add a client-side token bucket sized to your tier's published limits
  • Cache prompts: cached reads count less against ITPM
  • Request a tier upgrade if you sustain >80% utilization

Retry guidance

Retry after the retry-after header; otherwise exponential backoff starting at 1s, ×2 per attempt with jitter, max ~5 retries.

// Retry 429 with exponential backoff + full jitter.
async function callWithBackoff(payload: unknown, maxAttempts = 5) {
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
    const res = await fetch("https://api.anthropic.com/v1/messages", {
      method: "POST",
      headers: {
        "content-type": "application/json",
        "x-api-key": process.env.ANTHROPIC_API_KEY!,
      "anthropic-version": "2023-06-01",
      },
      body: JSON.stringify(payload),
    });
    if (res.status !== 429) return res;
    // Honor Retry-After when present; otherwise exponential backoff, capped at 32s.
    const retryAfter = Number(res.headers.get("retry-after"));
    const base = Number.isFinite(retryAfter) && retryAfter > 0
      ? retryAfter * 1000
      : Math.min(1000 * 2 ** attempt, 32_000);
    await new Promise((r) => setTimeout(r, base * (0.5 + Math.random() * 0.5)));
  }
  throw new Error("Anthropic 429: still failing after backoff — check https://status.anthropic.com");
}

Provider status page: status.anthropic.com