← Blog

Claude API Request Timeout: Configuration & Fix

2026-10-26 · 4 min read · SubToAPI Team

Why Claude API requests time out

Claude API requests time out when a response — especially for long completions, large context windows, or tool-use chains — takes longer to generate than your HTTP client is configured to wait. This is almost never a problem with the model itself; it's a mismatch between your client's timeout setting (often a default of 10–30 seconds) and how long a large or complex generation actually takes.

The fix has three parts: raise your client-side timeout to match realistic generation times, use streaming so you get data immediately instead of waiting for the full response, and add retry logic for the rare cases where a request genuinely stalls. Below is exactly how to configure each one, with working code.

Step 1: Increase your HTTP client timeout

Most timeout errors come from default values in HTTP libraries, not from Claude. fetch, axios, requests, and most SDKs ship with conservative defaults that are fine for small APIs but too short for LLM completions, which can legitimately take 30–120 seconds for long outputs.

Node.js (fetch with AbortController):

const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 120_000); // 120s

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({
    model: "claude-sonnet-4",
    max_tokens: 4096,
    messages: [{ role: "user", content: "Summarize this 50-page report..." }]
  }),
  signal: controller.signal
});

clearTimeout(timeout);

curl:

curl https://api.subtoapi.app/v1/messages \
  -H "Authorization: Bearer $SUBTOAPI_KEY" \
  -H "Content-Type: application/json" \
  --max-time 120 \
  -d '{
    "model": "claude-sonnet-4",
    "max_tokens": 4096,
    "messages": [{"role":"user","content":"Summarize this document..."}]
  }'

Python (requests):

import requests

response = requests.post(
    "https://api.subtoapi.app/v1/messages",
    headers={"Authorization": f"Bearer {api_key}"},
    json={
        "model": "claude-sonnet-4",
        "max_tokens": 4096,
        "messages": [{"role": "user", "content": "..."}]
    },
    timeout=120  # seconds
)

A good baseline: set timeouts to at least 60 seconds for normal requests, and 120–180 seconds if you're generating large outputs (max_tokens above 4000) or using tool-use chains with multiple round trips.

Step 2: Use streaming to avoid timeouts entirely

The most reliable fix isn't a longer timeout — it's not waiting for the full response at all. Streaming sends tokens back as they're generated, so your connection stays active and your client gets the first byte in under a second, regardless of total completion length.

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({
    model: "claude-sonnet-4",
    max_tokens: 4096,
    stream: true,
    messages: [{ role: "user", content: "Write a detailed analysis..." }]
  })
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  process.stdout.write(decoder.decode(value));
}

With streaming, a "timeout" almost always means the connection stalled with no data at all, not that the response is just long. That makes it much easier to distinguish a real network problem from a slow-but-healthy generation. See /docs/streaming for the full event format and reconnection patterns.

Step 3: Handle reverse proxy and load balancer timeouts

If you're running behind nginx, an ALB, Cloudflare, or another proxy, the proxy's own timeout can kill the connection even if your application code is configured correctly. This is a common cause of "it works locally but times out in production."

nginx example:

location /api/ {
    proxy_read_timeout 180s;
    proxy_send_timeout 180s;
    proxy_connect_timeout 10s;
}

AWS ALB: increase the idle timeout attribute on the load balancer (default is 60s) to at least 120s for routes that proxy LLM completions.

Check every layer between your code and the model: client library, application server, reverse proxy, CDN, and any API gateway. Each one has its own default, and the shortest one wins.

Step 4: Add retry logic for transient stalls

Even with correct timeouts, occasional network blips happen. Retry with exponential backoff on timeout errors specifically — not on 4xx errors, which won't resolve on retry.

async function callWithRetry(payload, attempts = 3) {
  for (let i = 0; i < attempts; i++) {
    try {
      const controller = new AbortController();
      const timeout = setTimeout(() => controller.abort(), 90_000);
      const res = 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
      });
      clearTimeout(timeout);
      if (res.ok) return await res.json();
    } catch (err) {
      if (i === attempts - 1) throw err;
      await new Promise(r => setTimeout(r, 2 ** i * 1000));
    }
  }
}

Reduce timeout risk at the source

Configuration fixes help, but reducing the amount of work per request matters too:

If you're switching from raw Claude API calls to a managed layer, SubToAPI exposes the same /v1/messages interface with streaming and usage metadata built in, so you can apply the same timeout and retry patterns above without changing your request shape. Check /docs/quickstart to get an API key and /docs/messages for the full request/response reference.

Questions

What's a safe default timeout for Claude API requests? 60 seconds for short completions, 120–180 seconds for large max_tokens values or multi-step tool-use requests. Streaming reduces the need for long timeouts since you receive data immediately.

Why does my request time out even after increasing the client timeout? Check intermediate layers — reverse proxies, load balancers, and API gateways often enforce their own shorter timeout independent of your application code.

Should I retry every timeout error automatically? Only retry on actual timeouts or connection errors with exponential backoff. Don't retry on 4xx errors like invalid requests or rate limits (429s), since retrying won't fix those and can make rate limiting worse.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →