Set a request timeout

Put a timeout on a request so you never hang forever on a slow or unresponsive server. Most defaults are effectively infinite, so set one explicitly.

Overview

Put a timeout on a request so you never hang forever on a slow or unresponsive server. Most defaults are effectively infinite, so set one explicitly.

In code

# cap the whole transfer and the connect phase separately:
curl --max-time 10 --connect-timeout 3 https://api.example.com/slow
// AbortController + timeout (or AbortSignal.timeout(ms)):
const ctrl = new AbortController();
const id = setTimeout(() => ctrl.abort(), 5000);
try {
  const res = await fetch('https://api.example.com/slow', { signal: ctrl.signal });
  return await res.json();
} finally {
  clearTimeout(id);
}
import requests

# (connect timeout, read timeout) in seconds
try:
    res = requests.get('https://api.example.com/slow', timeout=(3, 10))
except requests.Timeout:
    print('request timed out')

Details

Think of timeouts in two phases: the time to establish the connection (`--connect-timeout`, first value of the requests tuple) and the total transfer time (`--max-time`, second value = read timeout). Failing the connect fast while allowing a longer read is a useful split.

Browser `fetch` has no option-based timeout, so implement it with `AbortController`, or use `AbortSignal.timeout(ms)` in modern runtimes. A timeout throws an `AbortError`, which you catch to drive retries or fallbacks.

Combining timeouts with retries needs care: the request may actually reach and run on the server while only the client times out, so blindly retrying a non-idempotent POST can cause duplicates. Use an `Idempotency-Key` or restrict retries to idempotent requests. A server that exceeds its own limits may return 408 or 504.

Related headers

Related status codes