Claude API Timeout Configuration Guide
Timeout errors are one of the most common production issues developers hit when integrating Claude into real applications. A request that works fine in testing suddenly hangs for 30+ seconds on a long completion, a proxy drops the connection mid-stream, or a tool-use loop never returns because no timeout was set at all. This guide walks through exactly how to configure timeouts for Claude API requests — at the client, network, and application layer — so your app fails fast and recovers gracefully instead of hanging indefinitely.
The short answer: there is no single "timeout setting" in the Claude API itself. Timeouts are controlled by your HTTP client, your reverse proxy or load balancer, and how you structure streaming vs. non-streaming requests. Getting this right means setting different timeout values for different request types, because a simple chat message and a long agentic tool-use chain have very different latency profiles.
Why timeout configuration matters for Claude
Claude's response time scales with output length, model choice, and whether you're using extended thinking or chaining tool calls. A short answer might return in 1-2 seconds. A long document generation or multi-step agent workflow can legitimately take 60-120 seconds. If your HTTP client has a hardcoded 10-second timeout, you'll see sporadic failures that look like API instability but are actually just your own client cutting the connection too early.
The opposite problem is just as damaging: if you never set a timeout, a single hung connection (network blip, proxy issue, client disconnect) can tie up a worker process or connection pool slot indefinitely, degrading throughput for every other request behind it.
Three layers where timeouts apply
1. Client library / HTTP timeout — the maximum time your code waits for a response before throwing an error.
2. Network / proxy timeout — load balancers, API gateways, and reverse proxies (nginx, Cloudflare, AWS ALB) often have their own idle and total timeout settings that override your application code if set lower.
3. Streaming idle timeout — for streamed responses, you care less about total duration and more about whether tokens keep arriving. A stream that pauses for 30 seconds between chunks is a different failure mode than a non-streaming call that takes 30 seconds total.
Setting a request timeout with curl
curl https://api.anthropic.com/v1/messages \
--max-time 60 \
--connect-timeout 5 \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Summarize this report"}]
}'
--connect-timeout bounds how long to wait for the TCP/TLS handshake. --max-time bounds the entire request lifecycle. Keep the connect timeout short (3-5s) since a slow handshake almost always indicates a network problem, not a slow model response.
Setting a timeout in JavaScript with AbortController
async function callClaude(payload, timeoutMs = 45000) {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), timeoutMs);
try {
const response = await fetch("https://api.subtoapi.app/v1/messages", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SUBTOAPI_KEY}`,
"content-type": "application/json",
},
body: JSON.stringify(payload),
signal: controller.signal,
});
return await response.json();
} finally {
clearTimeout(timer);
}
}
This pattern works whether you're calling Anthropic's API directly or a gateway like SubToAPI — the timeout logic lives entirely in your fetch/axios layer, not in the API itself.
Recommended timeout values by workload
| Request type | Suggested timeout | Notes | |---|---|---| | Short chat reply (< 500 output tokens) | 15–20s | Fails fast on genuine issues | | Long-form generation (1k–4k tokens) | 60–90s | Scale with max_tokens | | Streaming responses | No total timeout; use idle timeout (20–30s between chunks) | Measure gaps, not total duration | | Tool use / multi-turn agent loops | 120–180s per full loop | Each tool round-trip adds latency | | Batch or background jobs | 300s+ or async processing | Don't block a web request on this |
A good rule of thumb: set your timeout to roughly 3-4x the P95 latency you observe in production for that specific request type, not a single global number across your whole app.
Streaming changes the timeout math
For streaming requests, total duration is the wrong thing to bound — a long but healthy stream can legitimately run for minutes. What you actually want to detect is a stalled stream: no new chunk arriving for N seconds. Implement this with a rolling timer that resets on every received chunk and only fires if the gap exceeds your threshold. See /docs/streaming for an example of handling server-sent events with per-chunk timeout resets.
Handling timeouts gracefully
Don't just catch the timeout error and give up — build a retry strategy:
- Use exponential backoff (1s, 2s, 4s) with a cap of 2-3 retries for transient network timeouts.
- Don't retry a timed-out request that has side effects (e.g., triggered a tool call with write access) without checking idempotency first.
- Log the timeout duration and request type so you can tune thresholds based on real data instead of guessing.
- Distinguish between a client-side timeout (your code gave up) and a genuine API error (rate limit, 5xx) — they need different handling.
Where SubToAPI fits in
If you're turning a Claude subscription into an internal API for your team, SubToAPI gives you a standard HTTPS endpoint with application-scoped keys (sub_live_...), so the same timeout patterns above apply whether you're calling Anthropic directly or routing through SubToAPI. You get streaming, tool use, and usage metadata in the response, which makes it easier to correlate slow requests with specific token counts or tool calls when you're tuning timeout thresholds. Check /docs/messages and /docs/tools for request/response formats, or start with /docs/quickstart if you're setting this up for the first time. Plans and seat pricing are on /pricing.
questions
What's a safe default timeout for the Claude API? For non-streaming chat requests, 30-60 seconds is a reasonable default. Scale it up for longer max_tokens values and multi-step tool-use workflows, which can legitimately take 2-3 minutes.
Should I set a timeout on streaming requests? Set an idle/gap timeout (20-30 seconds between chunks) instead of a total duration timeout. Streams can run long while remaining healthy, so measuring gaps between tokens is more reliable than capping total time.
Why does my proxy or load balancer time out before my code does? Infrastructure like nginx, Cloudflare, or AWS ALB often has its own idle timeout (commonly 30-60s) that can cut connections before your application-level timeout fires. Check and raise these limits to match your longest expected Claude response time.