The command
curl --connect-timeout 5 --max-time 20 https://httpbin.org/delay/3
What the flags do
| Flag | What it does |
|---|---|
--connect-timeout S | Maximum time to establish the connection, including DNS and TLS. |
-m S, --max-time S | Maximum time for the whole operation, start to finish. |
--retry N | Retry up to N times on transient failures. |
--retry-delay S / --retry-max-time S | Fixed wait between retries, and a cap on total retry time. |
--speed-limit B --speed-time S | Abort if slower than B bytes per second for S seconds. |
Two limits for two failure modes
--connect-timeout covers the phase where nothing has been agreed yet: resolving the name, opening the socket, completing the TLS handshake. A host that is down or firewalled fails here, and a few seconds is plenty. --max-time caps everything, including a response that starts and never finishes. Both accept fractions such as 2.5.
When either limit is hit curl exits with code 28. That is how a script tells "too slow" apart from "refused" (7) or "could not resolve" (6).
curl --connect-timeout 5 --max-time 20 -sS https://httpbin.org/delay/30
echo "exit code: $?" # 28
Retries
--retry repeats the request after timeouts and after responses such as 408, 429 and 5xx that suggest trying again. Without --retry-delay curl backs off on its own, doubling the wait each time, and it honours a Retry-After header. --max-time applies to each attempt, so bound the total with --retry-max-time.
Be deliberate about what you retry. Repeating a GET is harmless; repeating a POST that timed out after the server processed it creates a duplicate unless the API supports idempotency keys.
curl --retry 4 --retry-max-time 60 --connect-timeout 5 --max-time 15 \
-sS -f https://api.example.com/health
Large downloads
A total time limit is the wrong tool for a big file, since a healthy transfer may legitimately take an hour. Use a speed floor instead: give up only if the transfer has crawled below a threshold for a sustained period.
curl --connect-timeout 10 --speed-limit 1024 --speed-time 30 -O https://example.com/big.iso
Common mistakes
--max-timeincludes connection time. A value smaller than--connect-timeoutmakes the latter pointless.- Connection refused is not retried by default. Add
--retry-connrefused, or--retry-all-errorson curl 7.71+. - A timeout does not cancel work on the server. The request may still complete there after curl has given up.
Related curl examples
Curl Keep-Alive Example
"Keep-alive" names two unrelated mechanisms, and curl has switches for both.
Curl Download File Example
Curl prints what it downloads to the terminal unless told to save it.
Curl Proxy Server Example
-x routes a request through a proxy.
Curl Flags Example
Curl has well over two hundred options.
All Curl Examples
49 worked examples, grouped by what you are trying to do.
More under Network behaviour
References
- curl man page: -m — The --max-time limit on the whole transfer.
- curl man page: --connect-timeout — The limit on the connection phase.
These links leave api-tester.com, which is independent of the projects they point to.
FAQ
How do I set a timeout in curl?
Use --max-time (or -m) with a number of seconds for the whole request, and --connect-timeout to limit only the connection phase.
What is curl error 28?
Exit code 28 means the operation timed out: either the connection or the whole transfer exceeded the limit that was set.
What is the default timeout in curl?
There is no limit on the whole transfer by default. Only the connection phase has one, of about five minutes, so a server that accepts the connection and then stalls can hold curl open indefinitely.