# How to Handle Long-Running Requests and Avoid Timeouts in the Anthropic Python SDK

> Avoid Anthropic Python SDK timeouts with stream=True or custom timeouts. Safely handle long-running requests and prevent interruptions in your Python applications.

- Repository: [Anthropic/anthropic-sdk-python](https://github.com/anthropics/anthropic-sdk-python)
- Tags: how-to-guide
- Published: 2026-02-23

---

**Enable streaming (`stream=True`) for any request that might exceed 10 minutes, or provide a custom `timeout` value to bypass the non-streaming guard and handle long-running requests safely.**

The Anthropic Python SDK enforces strict timeout defaults to prevent hanging connections, automatically rejecting non-streaming requests that could take longer than 10 minutes. Understanding how to handle long-running requests and potential timeouts is essential for production applications using the `anthropics/anthropic-sdk-python` repository.

## Default Timeout Behavior in the SDK

The SDK initializes every client with a **10-minute default timeout** defined in [`src/anthropic/_constants.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_constants.py):

```python

# src/anthropic/_constants.py

DEFAULT_TIMEOUT = httpx.Timeout(timeout=10 * 60, connect=5.0)  # 600 seconds total

```

This value propagates to the `BaseClient` class in [`src/anthropic/_base_client.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_base_client.py), where it becomes the client-wide timeout unless explicitly overridden during initialization or per-request.

## The Non-Streaming Guard for Long-Running Requests

To prevent users from accidentally triggering timeouts, the SDK implements a proactive guard in `BaseClient._calculate_nonstreaming_timeout` that estimates processing time and forces streaming for long jobs.

### How the Guard Calculates Risk

The method assumes a worst-case processing speed of **128,000 tokens per hour** (approximately 35 tokens per second). It calculates the expected duration and raises a `ValueError` if the request exceeds safe thresholds:

```python

# src/anthropic/_base_client.py

def _calculate_nonstreaming_timeout(self, max_tokens: int, max_nonstreaming_tokens: int | None) -> Timeout:
    maximum_time = 60 * 60          # 1 hour (theoretical upper bound)

    default_time = 60 * 10           # 10 minutes

    expected_time = maximum_time * max_tokens / 128_000
    if expected_time > default_time or (max_nonstreaming_tokens and max_tokens > max_nonstreaming_tokens):
        raise ValueError(
            "Streaming is required for operations that may take longer than 10 minutes. "
            + "See https://github.com/anthropics/anthropic-sdk-python#long-requests for more details",
        )
    return Timeout(default_time, connect=5.0)

```

### Where the Guard Is Applied

The check executes in [`src/anthropic/resources/messages/messages.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/resources/messages/messages.py) within the `create` method, but only when three conditions are met:

```python

# src/anthropic/resources/messages/messages.py

if not stream and not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT:
    timeout = self._client._calculate_nonstreaming_timeout(
        max_tokens, MODEL_NONSTREAMING_TOKENS.get(model, None)
    )

```

This means the guard is bypassed if you explicitly provide a custom timeout or enable streaming.

## Strategies to Handle Long-Running Requests

### Enable Streaming for Large Generations

**Streaming** is the recommended approach for any request that might exceed 10 minutes. When `stream=True`, the SDK returns a `Stream` object that yields events as they arrive, keeping the connection alive indefinitely:

```python
from anthropic import Anthropic

client = Anthropic()

stream = client.messages.create(
    max_tokens=12_000,
    model="claude-3-opus-20240229",
    messages=[{"role": "user", "content": "Write a comprehensive 50-page technical manual."}],
    stream=True,  # Bypasses the non-streaming guard

)

for event in stream:
    if event.type == "content_block_delta":
        print(event.delta.text, end="", flush=True)

```

### Provide a Custom Timeout

To handle long-running requests in non-streaming mode, override the default timeout. Any value different from `DEFAULT_TIMEOUT` disables the automatic guard:

```python
from anthropic import Anthropic

# Set a 20-minute timeout

client = Anthropic(timeout=1200.0)

response = client.messages.create(
    max_tokens=4_000,
    model="claude-3-sonnet-20240229",
    messages=[{"role": "user", "content": "Generate a detailed legal contract."}],
    stream=False,
)

```

You can also set timeouts per-request using `with_options`:

```python
response = client.with_options(timeout=900.0).messages.create(
    max_tokens=3_000,
    model="claude-3-haiku-20240307",
    messages=[{"role": "user", "content": "Analyze this 100-page document."}],
)

```

### Reduce max_tokens to Stay Under the Limit

If you prefer non-streaming responses but want to avoid the guard, calculate your token budget to stay under the 10-minute threshold. Based on the SDK's 128k tokens/hour assumption:

- **Safe limit**: Approximately 21,000 tokens (128,000 ÷ 60 × 10)
- **Conservative limit**: 20,000 tokens or fewer

```python

# Safe non-streaming request

response = client.messages.create(
    max_tokens=20_000,  # Under the ~21k token threshold

    model="claude-3-opus-20240229",
    messages=[{"role": "user", "content": "Summarize quantum computing."}],
    stream=False,
)

```

### Adjust Retry Behavior for Timeout Resilience

The SDK automatically retries on timeouts using exponential backoff. You can adjust this behavior via the `max_retries` parameter (default is 2):

```python
from anthropic import Anthropic

# Increase retries for flaky networks

client = Anthropic(max_retries=5)

# Or disable retries entirely for strict timeout control

client = Anthropic(max_retries=0)

```

## How the SDK Handles Timeout Errors

When a request exceeds its timeout, the SDK implements a sophisticated retry mechanism in `BaseClient.request`:

1. **httpx** raises `httpx.TimeoutException`
2. The SDK catches this in [`src/anthropic/_base_client.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_base_client.py) and checks remaining retries
3. If retries remain, it calls `_sleep_for_retry` with exponential backoff and jitter
4. After final attempt, it raises `APITimeoutError`:

```python

# src/anthropic/_base_client.py (excerpt)

except httpx.TimeoutException as err:
    log.debug("Encountered httpx.TimeoutException", exc_info=True)

    if remaining_retries > 0:
        self._sleep_for_retry(...)
        continue

    log.debug("Raising timeout error")
    raise APITimeoutError(request=request) from err

```

## Complete Code Examples

### Streaming a Massive Generation

```python
from anthropic import Anthropic, APITimeoutError

client = Anthropic()

try:
    stream = client.messages.create(
        max_tokens=12_000,
        model="claude-3-opus-20240229",
        messages=[{"role": "user", "content": "Write a 30-page novel about space exploration"}],
        stream=True,
    )
    
    for event in stream:
        if event.type == "content_block_delta":
            print(event.delta.text, end="", flush=True)
            
except APITimeoutError:
    print("Even streaming timed out – check network conditions.")

```

### Custom Timeout for Controlled Non-Streaming

```python
from anthropic import Anthropic, APITimeoutError

# 20-minute timeout overrides the default guard

client = Anthropic(timeout=1200.0)

try:
    resp = client.messages.create(
        max_tokens=3_000,
        model="claude-3-sonnet-20240229",
        messages=[{"role": "user", "content": "Generate a 15-page research summary."}],
        stream=False,
    )
    print(resp.content)
except APITimeoutError:
    print("Request exceeded 20 min – consider streaming or splitting the job.")

```

### Adjusting Retries and Handling Rate Limits

```python
from anthropic import Anthropic, RateLimitError, APITimeoutError

client = Anthropic(max_retries=5)   # More aggressive retry policy

try:
    result = client.messages.create(
        max_tokens=4_000,
        model="claude-3-opus-20240229",
        messages=[{"role": "user", "content": "Explain quantum computing in depth."}],
        stream=False,
    )
    print(result.content)
except RateLimitError as e:
    print(f"Rate limited, wait {e.retry_after}s before retrying")
except APITimeoutError:
    print("Operation timed out – maybe split into smaller chunks")

```

## Summary

- **Default timeout**: The SDK enforces a 10-minute default timeout via `DEFAULT_TIMEOUT` in [`src/anthropic/_constants.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_constants.py).
- **Non-streaming guard**: The `_calculate_nonstreaming_timeout` method in [`src/anthropic/_base_client.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_base_client.py) raises `ValueError` for non-streaming requests estimated to exceed 10 minutes.
- **Streaming solution**: Enable `stream=True` to bypass the guard and handle long-running requests safely without timeout limits.
- **Custom timeouts**: Pass a custom `timeout` value (different from the default) to disable the guard for non-streaming requests.
- **Retry logic**: The SDK automatically retries on `APITimeoutError` with exponential backoff; adjust `max_retries` to control this behavior.

## Frequently Asked Questions

### What is the default timeout in the Anthropic Python SDK?

The default timeout is **10 minutes** (600 seconds), defined as `httpx.Timeout(timeout=10 * 60, connect=5.0)` in [`src/anthropic/_constants.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_constants.py). This applies to all requests unless you provide a custom timeout during client initialization or per-request.

### Why does the SDK force streaming for long requests?

The SDK protects users from accidental timeouts by calculating the expected processing time in `BaseClient._calculate_nonstreaming_timeout`. If a non-streaming request is estimated to take longer than 10 minutes based on the `max_tokens` value (assuming 128,000 tokens/hour processing speed), it raises a `ValueError` requiring you to enable streaming.

### How can I disable the non-streaming guard?

You can bypass the guard by providing a **custom timeout** that differs from `DEFAULT_TIMEOUT`. For example, initializing the client with `Anthropic(timeout=1200.0)` disables the check because the guard only triggers when `self._client.timeout == DEFAULT_TIMEOUT`. Alternatively, use `stream=True` to avoid the check entirely.

### What exception is raised when a request times out?

When a request exceeds its timeout after all retry attempts, the SDK raises `APITimeoutError`. This exception wraps the underlying `httpx.TimeoutException` and includes the request details. You can catch this to implement fallback logic, such as switching to streaming or splitting the request into smaller chunks.