CLAUDE LABJP
FORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtaskLIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its ownMCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSPLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callbackSONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as OctoberFORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtaskLIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its ownMCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSPLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callbackSONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as October
Articles/API & SDK
API & SDK/2026-04-22Intermediate

Handling Frequent 529 Overloaded Errors from the Claude API — A Practical Playbook

A 529 Overloaded response from the Claude API is a very different animal from a 429 rate limit. Here is the retry, fallback, and circuit breaker playbook I actually use in production to keep services responsive when Anthropic's platform is temporarily saturated.

api38troubleshooting87overloaded25292resilience10

You have already implemented proper rate limit handling. 429s are handled gracefully. Then one evening, your Slack bot's error channel starts filling up with a code you have never seen before: 529 Overloaded. That was my experience a few weeks after shipping a production integration, and the instinct to "slow down requests" turned out to be the wrong reflex entirely. The short version: 529 is not an error your application caused. It is a signal that Anthropic's platform itself is temporarily saturated, and the mitigation has to cover how you wait, how you route, and how you degrade.

This article distills the patterns I rely on in production — the ones that actually move the needle when 529 starts showing up in logs.

529 Is Not Your Fault — And That Changes Everything

In Anthropic's error reference, 529 is defined as "The API is temporarily overloaded." The crucial distinction is with its close neighbors. 429 means your own usage has hit the quota assigned to your plan — tokens per minute, requests per minute, or input tokens per day. 503 indicates the service is unavailable for maintenance or unexpected downtime. 529, by contrast, can happen while your own quota still has plenty of headroom; it simply means demand across the platform is outrunning capacity right now.

The practical consequence is that spacing out your requests does not fix 529 the way it fixes 429. The first time I hit 529 in production, my request rate was actually below my normal baseline. Logs showed "type": "overloaded_error" with status code 529. Anthropic's status page confirmed a temporary load spike in the North America region. What brought the service back to healthy was not a smaller request budget, but a combination of smarter retries and a model cascade — both covered below.

Step One: Confirm It Is Actually a 529

Before you start applying fixes, make sure you can distinguish 529 from its neighbors in your logs. If you are catching everything as a generic APIError, you cannot branch retry strategy on error type. With the Python SDK, split them using APIStatusError and its subclasses.

import anthropic
from anthropic import APIStatusError, APIConnectionError
 
client = anthropic.Anthropic()
 
def call_with_classification(messages):
    try:
        return client.messages.create(
            model="claude-sonnet-4-6",
            max_tokens=1024,
            messages=messages,
        )
    except APIStatusError as e:
        err_type = (e.response.json().get("error") or {}).get("type")
        print(f"[API {e.status_code}] type={err_type}")
        raise
    except APIConnectionError as e:
        print(f"[Connection] {e}")
        raise
 
# Expected output during an overload: [API 529] type=overloaded_error

From there, you branch on err_type — typically overloaded_error vs rate_limit_error — and pick the retry policy that fits. Without that separation, you end up with a blunt "wait longer" strategy that burns time even for errors that would benefit from a completely different approach.

One practical tip: also log the request-id header from the SDK response when you catch an overload. During incidents, Anthropic support can correlate a few of those IDs to regional capacity telemetry much faster than a generic description of symptoms. I keep a tiny helper that extracts request-id, timestamp, model, and input token count into a dedicated overload log file separate from the main application log.

Exponential Backoff With Jitter Is Necessary but Not Sufficient

The baseline for retrying 529 is exponential backoff with randomized jitter. If every client retries at exactly the same interval, they recreate the overload the moment the platform starts recovering. The pattern I use is "Full Jitter," described in detail on the AWS Builders' Library.

import random
import time
from anthropic import APIStatusError
 
def call_with_full_jitter(fn, max_retries=6, base=1.0, cap=60.0):
    """
    Full Jitter retry. Only retries on 429/529/503; leaves 4xx alone.
    """
    attempt = 0
    while True:
        try:
            return fn()
        except APIStatusError as e:
            if e.status_code not in (429, 529, 503):
                raise
            if attempt >= max_retries:
                raise
            sleep = random.uniform(0, min(cap, base * (2 ** attempt)))
            time.sleep(sleep)
            attempt += 1
 
# Expected behavior: on repeated 529s, wait windows expand from
# up to 1s, 2s, 4s, 8s... while avoiding synchronized retries.

Full Jitter alone will pull you through most short overload windows. When the overload is wider or longer, backoff buys time but will not keep a realtime UX acceptable. That is where the next two layers earn their keep.

The Production-Grade Combo: Model Cascade and Regional Diversity

When you cannot make the user wait, give them a slightly lower-quality answer instead of a failure. A model cascade retries with a lighter, faster model if the primary model is overloaded. Sonnet unavailable for a few seconds? Fall back to Haiku for that request.

MODEL_CASCADE = ["claude-sonnet-4-6", "claude-haiku-4-5"]
 
def resilient_call(messages, max_retries_per_model=3):
    last_err = None
    for model in MODEL_CASCADE:
        try:
            return call_with_full_jitter(
                lambda: client.messages.create(
                    model=model,
                    max_tokens=1024,
                    messages=messages,
                ),
                max_retries=max_retries_per_model,
            )
        except APIStatusError as e:
            if e.status_code != 529:
                raise
            last_err = e
            continue
    raise last_err

The second layer is regional and provider diversity. The Anthropic direct API, Amazon Bedrock, and Google Cloud Vertex AI all host Claude but on independent capacity pools. During real overload events, they rarely degrade in perfect sync — one is often fine while another is saturated. If you run a service with SLA commitments, this is the single highest-leverage insurance policy you can buy. Setup takes some work; my walkthrough for the Bedrock side lives in the Claude API × Amazon Bedrock production guide.

A Circuit Breaker Stops You From Paying for a Broken Path

Retries alone have a failure mode: they keep hammering a degraded endpoint and waste both time and tokens. A circuit breaker trips the sending path open after a burst of failures so you stop sending for a cooldown window. If 5 × 529 show up inside 60 seconds, stop sending to the direct API for 120 seconds and route only to the fallback path.

import time
from collections import deque
from threading import Lock
 
class CircuitBreaker:
    def __init__(self, failure_threshold=5, window_sec=60, open_sec=120):
        self.failures = deque()
        self.window = window_sec
        self.threshold = failure_threshold
        self.open_sec = open_sec
        self.opened_at = None
        self.lock = Lock()
 
    def allow(self):
        with self.lock:
            now = time.time()
            if self.opened_at and now - self.opened_at < self.open_sec:
                return False
            if self.opened_at:
                self.opened_at = None
            return True
 
    def record_failure(self):
        with self.lock:
            now = time.time()
            self.failures.append(now)
            while self.failures and now - self.failures[0] > self.window:
                self.failures.popleft()
            if len(self.failures) >= self.threshold:
                self.opened_at = now
 
# Expected behavior: after 5 × 529 within a 60s window, allow() returns
# False for 120s, and upstream code routes to the fallback path.

Libraries like pybreaker in Python or opossum in Node.js offer more features, but the 30-line version above is often enough for early production. Emit a metric each time the breaker opens; that single graph will tell you more about Anthropic's platform health than most monitoring setups I have seen.

One subtlety worth noting: you want separate breaker instances per upstream, not a single global one. If the direct Anthropic API is overloaded but Bedrock is healthy, a global breaker would incorrectly block traffic to Bedrock as well. Keying breakers by (provider, region) keeps each path independent, which is exactly the property that makes the fallback design pay off during a real incident.

Non-Code Levers: Priority Tier and Batches API

Two more levers are worth remembering because they live outside your application code.

The first is Anthropic's Priority Tier on paid plans. Higher tiers are prioritized when the platform is under pressure, which reduces how often 529 reaches your traffic at all. For B2B workloads with strict SLAs, the cost can be justified directly from availability numbers. I cover the implementation details in the Claude API production rate limit & billing guide.

The second is the Batches API. Any workload that does not need sub-second latency — nightly summaries, large analytical passes, offline enrichment — should go through Batches rather than synchronous requests. That removes load from your synchronous path and, by extension, reduces your exposure to 529. The practical migration playbook is in the Claude API Batches async processing guide.

The Single Step You Can Take Today

The right goal for 529 is not to prevent it — you cannot — but to keep the user experience intact when it arrives. Before you touch anything else, check whether Full Jitter retries are in your production code path. If they are not, adding the thirty lines above silently absorbs more than half of the 529s you were seeing. From there, add a circuit breaker and a model cascade and you will have a service that stays useful even when the platform is having a bad afternoon.

Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

API & SDK2026-05-23
Absorbing Claude API 529 Overloaded in Production — Resilience Patterns from a 50M-Download Indie Studio
529 Overloaded won't go away with a naive exponential backoff. Drawing on lessons from 50 million app downloads, this piece walks through queue-based absorption, model-aware fallback, and circuit-breaker design with working code.
API & SDK2026-05-16
Debugging Claude API Tool Use Schema Errors: 3 Patterns I've Hit and How to Fix Them
A practical guide to diagnosing Claude API Tool Use errors—from schema definition mistakes to invalid_tool_use blocks and Claude ignoring your tools entirely. Based on real implementation experience.
API & SDK2026-05-04
Claude API stop_sequences Not Working — 5 Things to Check Before You Give Up
Diagnose why your Claude API stop_sequences parameter isn't halting generation as expected. Practical breakdown of token boundaries, whitespace mismatches, Tool Use interactions, and streaming pitfalls — with copy-paste code examples.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →