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 timeoutDEFAULT_MAX_RETRIES = 2allows 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 any5xxserver errors - The
x-should-retryresponse header when set to"true"
Backoff Strategy
Retry delays follow an exponential pattern with jitter:
- Initial delay: 0.5 seconds (
INITIAL_RETRY_DELAYin_constants.py) - Growth:
INITIAL_RETRY_DELAY * 2**retry_numbercapped 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
timeoutandmax_retriesin theAnthropicorAsyncAnthropicconstructor to define defaults for all requests - Per-request overrides: Pass
timeout(asfloatorhttpx.Timeout) andmax_retries(asint) to individual resource methods likecompletions.create()ormessages.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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →