How to Configure Client Timeouts and Retry Mechanisms in the Anthropic Python SDK

The Anthropic Python SDK allows you to configure network timeouts and automatic retries globally via the Anthropic client constructor or override them per-request using the timeout and max_retries parameters.

The anthropics/anthropic-sdk-python library provides granular control over HTTP request resilience, letting you fine-tune connection behavior for both short-lived prompts and long-running content generation tasks. You can set defaults that apply to all API calls or specify custom timeouts and retry limits for individual completions and messages.

Client-Wide Timeout and Retry Configuration

Define default behavior when instantiating the Anthropic or AsyncAnthropic client. In src/anthropic/_client.py, the constructor accepts timeout and max_retries parameters that persist across all subsequent requests.

Default values are defined in src/anthropic/_constants.py:

  • DEFAULT_TIMEOUT = httpx.Timeout(timeout=10*60, connect=5.0) sets a 10-minute read timeout and 5-second connect timeout
  • DEFAULT_MAX_RETRIES = 2 allows up to three total attempts (initial request plus two retries)

Pass a float for simple read timeout adjustments, or an httpx.Timeout object for granular control:

import anthropic
from httpx import Timeout

client = anthropic.Anthropic(
    api_key="YOUR_API_KEY",
    timeout=Timeout(read=30.0, connect=5.0, write=10.0, pool=5.0),
    max_retries=5,
)

Per-Request Timeout and Retry Overrides

Individual resource methods (.create(), .list(), etc.) accept timeout and max_retries parameters that supersede client-wide defaults. The implementation in src/anthropic/resources/completions.py and src/anthropic/resources/messages/messages.py validates these with is_given(timeout) checks, falling back to client defaults only when overrides are not provided.

Override settings for long-running requests:

response = client.messages.create(
    model="claude-3-5-sonnet-20240620",
    max_tokens=4096,
    messages=[{"role": "user", "content": "Analyze this 100-page document..."}],
    timeout=Timeout(read=8*60),  # 8 minutes for this specific call

    max_retries=4,
)

How the Retry Mechanism Works

The retry logic implemented in src/anthropic/_base_client.py provides resilient network handling through exponential backoff and error classification.

Retry Triggers

The _should_retry method initiates retries for:

  • HTTP status codes 408 (Request Timeout), 409 (Conflict), 429 (Rate Limit), and any 5xx server errors
  • The x-should-retry response header when set to "true"

Backoff Strategy

Retry delays follow an exponential pattern with jitter:

  • Initial delay: 0.5 seconds (INITIAL_RETRY_DELAY in _constants.py)
  • Growth: INITIAL_RETRY_DELAY * 2**retry_number capped at 60 seconds (MAX_RETRY_DELAY)
  • Jitter: Random variance of ±0.25 seconds applied to each delay

Rate Limit Awareness

When the API returns a Retry-After or retry-after-ms header, _parse_retry_after_header parses the value (in seconds or milliseconds) and uses that exact duration instead of the calculated backoff.

Idempotency Handling

Non-GET requests automatically receive an x-stainless-idempotency-key header generated by _idempotency_key() in _base_client.py. This key persists across retry attempts, ensuring the server can safely deduplicate repeated requests without side effects.

Practical Configuration Examples

Custom Client with Extended Timeouts

import anthropic
from httpx import Timeout

client = anthropic.Anthropic(
    api_key="sk-...",
    timeout=Timeout(read=45.0, connect=10.0),
    max_retries=3,
)

response = client.completions.create(
    model="claude-3-opus-20240229",
    max_tokens=1024,
    prompt="Generate a detailed technical specification.",
)

Async Client Configuration

import asyncio
import anthropic
from httpx import Timeout

async def main():
    async_client = anthropic.AsyncAnthropic(
        api_key="sk-...",
        timeout=Timeout(read=60.0, connect=5.0),
        max_retries=2,
    )
    resp = await async_client.messages.create(
        model="claude-3-haiku-20240307",
        max_tokens=500,
        messages=[{"role": "user", "content": "Hello!"}],
    )
    print(resp.content)

asyncio.run(main())

Streaming with Custom Timeouts

Streaming requests respect the configured timeout and retry policies during connection establishment, though the read timeout behavior adapts to the streaming context:

response = client.messages.create(
    model="claude-3-5-sonnet-20240620",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Tell me a story..."}],
    timeout=Timeout(read=5*60),  # 5 minutes for streaming

    max_retries=3,
    stream=True,
)

Summary

  • Global configuration: Set timeout and max_retries in the Anthropic or AsyncAnthropic constructor to define defaults for all requests
  • Per-request overrides: Pass timeout (as float or httpx.Timeout) and max_retries (as int) to individual resource methods like completions.create() or messages.create()
  • Default behavior: 10-minute read timeout, 5-second connect timeout, and 2 maximum retries (3 total attempts)
  • Retry logic: Automatic retries occur for HTTP 408, 409, 429, and 5xx status codes with exponential backoff (0.5s to 60s) and jitter
  • Idempotency: The SDK automatically handles idempotency keys for safe retry of state-changing requests

Frequently Asked Questions

How do I increase the timeout for a single long-running request without changing the client defaults?

Pass an httpx.Timeout object directly to the specific method call. For example, client.messages.create(timeout=Timeout(read=600), ...) overrides the client default for that request only, while other requests continue using the original client configuration.

What HTTP status codes trigger automatic retries in the Anthropic SDK?

According to _should_retry in src/anthropic/_base_client.py, the SDK retries requests returning status codes 408 (Request Timeout), 409 (Conflict), 429 (Rate Limit), and any 5xx (Server Error). Additionally, the x-should-retry header can force a retry when set to "true".

How does the SDK handle rate limiting with the Retry-After header?

The _parse_retry_after_header function in src/anthropic/_base_client.py parses both Retry-After (seconds) and retry-after-ms (milliseconds) headers. When present, the SDK sleeps for exactly the specified duration before the next attempt, bypassing the standard exponential backoff calculation for that specific retry cycle.

What is the maximum number of retries allowed, and how is the delay calculated?

The default maximum is 2 retries (3 total attempts), configurable via max_retries. Delays start at 0.5 seconds (INITIAL_RETRY_DELAY) and double with each attempt (0.5 * 2**retry_num), capped at 60 seconds (MAX_RETRY_DELAY), with random jitter of ±0.25 seconds applied to prevent thundering herd problems.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →