Fix Anthropic Claude API Timeouts: 504 Errors & Solutions (2026)
Claude API requests timing out with a 504 gateway error or an SDK APITimeoutError? Here’s how to diagnose the cause — connection timeout vs read timeout vs gateway timeout — and fix it with the right approach for your use case.
First step: if the Anthropic API status shows an active incident or degraded performance, timeouts are caused by infrastructure problems — not your code or settings. Wait for the incident to resolve before changing your timeout configuration.
Default Claude SDK timeout settings
Both official SDKs default to 10 minutes (600 s) for the total request duration. This covers the time from sending the request until receiving the last byte of the response. There is also a separate connection timeout of about 5 seconds for establishing the TCP connection.
| SDK | Default total timeout | Connection timeout |
|---|---|---|
Python anthropic | 600 s | 5 s |
Node.js @anthropic-ai/sdk | 600 s | 5 s |
| Raw HTTP / Go | depends on http.Client | depends on Dialer |
Step 1 — Increase the per-request or global timeout
If you control the full network path (e.g. a background job calling the API directly without a reverse proxy), increasing the timeout is the simplest fix. The Python SDK uses httpx.Timeout internally, which lets you set connection, read, write, and pool timeouts independently.
Python — per-request and global timeout
import anthropic
import httpx
# Option A: increase timeout globally on the client
client = anthropic.Anthropic(
api_key="sk-ant-api03-...",
timeout=httpx.Timeout(
connect=10.0, # TCP handshake
read=300.0, # wait for response bytes
write=30.0, # sending request body
pool=10.0, # waiting for a connection from the pool
),
)
# Option B: override timeout for a single request
message = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=4096,
messages=[{"role": "user", "content": "Summarize this 100-page document..."}],
timeout=httpx.Timeout(connect=10.0, read=300.0, write=30.0, pool=10.0),
)
print(message.content[0].text) TypeScript / Node.js — per-request and global timeout
import Anthropic from '@anthropic-ai/sdk';
// Option A: global timeout on the client (milliseconds)
const client = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
timeout: 300_000, // 5 minutes in ms
});
// Option B: per-request timeout override
const message = await client.messages.create(
{
model: 'claude-3-5-sonnet-20241022',
max_tokens: 4096,
messages: [{ role: 'user', content: 'Summarize this document...' }],
},
{
timeout: 300_000, // 5 minutes — overrides client default
}
);
console.log(message.content[0].text); Step 2 — Use streaming for user-facing or long requests
Streaming is the correct solution when requests go through a proxy or gateway you do not fully control. With streaming, the API sends response chunks immediately as they are generated — the connection is never idle, so gateways do not time out. This is also faster to first token for the user.
Python — streaming messages
import anthropic
client = anthropic.Anthropic(api_key="sk-ant-api03-...")
# Use stream() context manager — never idles, sidesteps gateway timeouts
with client.messages.stream(
model="claude-3-5-sonnet-20241022",
max_tokens=4096,
messages=[{"role": "user", "content": "Write a detailed analysis..."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
# Token counts available after stream completes
final = stream.get_final_message()
print(f"\n\nInput tokens: {final.usage.input_tokens}")
print(f"Output tokens: {final.usage.output_tokens}") TypeScript — streaming messages
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
const stream = client.messages.stream({
model: 'claude-3-5-sonnet-20241022',
max_tokens: 4096,
messages: [{ role: 'user', content: 'Write a detailed analysis...' }],
});
// Stream text chunks as they arrive
stream.on('text', (text) => process.stdout.write(text));
// Await the final message for usage stats
const final = await stream.finalMessage();
console.log(`\nTokens used: {final.usage.input_tokens} in / {final.usage.output_tokens} out`); Go — set timeout on the HTTP client
There is no official Anthropic Go SDK. Pass a custom http.Client with the timeout you need.
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
func main() {
// Use a context with timeout — cleanest approach in Go
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
body, _ := json.Marshal(map[string]any{
"model": "claude-3-5-sonnet-20241022",
"max_tokens": 4096,
"messages": []map[string]string{
{"role": "user", "content": "Summarize this document..."},
},
})
req, _ := http.NewRequestWithContext(ctx, http.MethodPost,
"https://api.anthropic.com/v1/messages",
bytes.NewReader(body),
)
req.Header.Set("x-api-key", "sk-ant-api03-...")
req.Header.Set("anthropic-version", "2023-06-01")
req.Header.Set("content-type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
// context.DeadlineExceeded means your timeout fired
fmt.Printf("request error: %v\n", err)
return
}
defer resp.Body.Close()
data, _ := io.ReadAll(resp.Body)
fmt.Println(string(data))
} Step 3 — Add retry logic for timeout errors
The SDK’s built-in max_retries handles 429 and 529 automatically but does not retry timeouts — a timed-out request may have already been processed server-side, so retrying could cause duplicate side effects. For idempotent completions, add your own retry with a timeout-specific check:
import anthropic
import time
import random
client = anthropic.Anthropic(api_key="sk-ant-api03-...")
def create_with_timeout_retry(max_attempts=3, **kwargs):
"""Retry on timeout and connection errors.
Only use for idempotent requests."""
for attempt in range(max_attempts):
try:
return client.messages.create(**kwargs)
except anthropic.APITimeoutError:
if attempt == max_attempts - 1:
raise
wait = (2 ** attempt) + random.random()
print(f"Timeout on attempt {attempt + 1}, retrying in {wait:.1f}s")
time.sleep(wait)
except anthropic.APIConnectionError:
# Network-level failure — safe to retry
if attempt == max_attempts - 1:
raise
time.sleep(2 ** attempt)
result = create_with_timeout_retry(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
) 504 vs 529 — different errors, different fixes
504 Gateway Timeout
A proxy or load balancer between your app and the Anthropic API killed the connection because no data arrived within its idle timeout. The Anthropic server may still be processing your request.
Causes
- nginx
proxy_read_timeoutis 60 s (default) - Cloudflare 100 s gateway timeout
- AWS ALB 60 s idle timeout
- Vercel / Next.js 60 s function timeout
Fix
Switch to streaming — the response starts flowing within milliseconds so the connection is never idle.
529 Overloaded
Anthropic’s servers received your request but rejected it immediately due to high load. Your request was never processed. Always safe to retry.
Causes
- Anthropic infrastructure degradation
- High global demand on a specific model
- Partial outage on a region
Fix
Retry with exponential backoff. The SDK’s max_retries handles 529 automatically. Check prismix.dev/service/anthropic for active incidents.
Get an email the next time Anthropic goes down
Outage alerts for Anthropic, straight to your inbox. No account needed, unsubscribe in every email.
Watching more than one service? A free account covers 5 services + a daily digest — and Pro is currently free.
Frequently Asked Questions
What is the default timeout for Anthropic Claude API?
Both the Python and Node.js SDKs default to 10 minutes (600 s) for the total request duration, with a 5 s connection timeout. This is the SDK-level timeout — your reverse proxy or serverless platform may have a shorter limit that triggers first.
Should I increase timeout or use the streaming API?
Use streaming for user-facing requests or any path with a proxy. Use a longer timeout only for batch background jobs on an infrastructure you fully control. Streaming prevents idle-connection kills that a longer timeout cannot fix.
What is the difference between 504 and 529 errors?
504 is a gateway timeout — a proxy killed the connection. Fix: use streaming. 529 is an Anthropic-side overload rejection. Fix: retry with backoff. They look similar but need different solutions.
How do I handle API timeouts in production?
Three layers: (1) Use streaming for interactive requests; (2) Set a per-request timeout that matches your SLA; (3) Retry on APITimeoutError and APIConnectionError separately from status errors — the SDK’s built-in max_retries does not retry timeouts by default.
Why does claude sdk timeout configuration differ from the raw API?
The SDK wraps httpx (Python) or node-fetch / undici (Node) under the hood. If you call the API directly via requests, axios, or http.Client, you must set the timeout yourself — there is no built-in default.