TLS and network control

Set timeouts and safe retries

Bound connection and total time, then retry only operations whose repetition is acceptable.

10 minute lesson

~~~

By default, curl waits a long time for a server that never answers. In a terminal that costs you patience. In automation it costs you a hung script, a stuck cron job, or a CI pipeline that blocks for minutes on a dead host. Network operations can hang or fail temporarily, so automation needs time bounds, clear exit codes, and a retry policy connected to what the operation actually does.

Bound the time

Add a connection timeout, total timeout, and limited retry:

curl --connect-timeout 3 --max-time 10 --retry 2 https://example.org/

The two timeouts answer different questions. --connect-timeout 3 bounds how long curl waits to establish the connection: DNS plus TCP plus the handshake. --max-time 10 bounds the entire transfer, including the download. A server that accepts connections instantly but dribbles out one byte per second sails past the first limit and hits the second.

Test once against an unreachable lab address:

time curl --connect-timeout 3 --max-time 10 https://10.255.255.1/
# curl: (28) Failed to connect to 10.255.255.1 port 443 after 3002 ms: Timeout was reached
echo $?   # 28

Record the elapsed time and final exit code instead of waiting indefinitely. Exit code 28 is curl’s timeout signal, and the roughly three-second duration proves the connection timeout did the work. Without these options the same command can hang for minutes.

Retry what deserves retrying

--retry 2 makes curl attempt the transfer up to two extra times, but only for failures curl considers transient: timeouts, plus HTTP responses like 408, 429, 500, 502, 503, and 504. A 404 does not get retried, and that is correct — the resource will still be missing on attempt three. curl also waits between attempts, backing off progressively, and you can cap the whole budget with --retry-max-time 30.

The safety rule

Retries can repeat side effects. Retrying a GET is harmless: reading twice changes nothing. Retrying a POST that creates an order can create two orders, because “the response timed out” does not mean “the server did nothing” — the request may have succeeded just as the connection dropped.

Use retries freely only for operations designed to be idempotent or protected by an idempotency key, where the server recognizes a repeated request and refuses to apply it twice. For everything else, a failure should surface to something that can decide, not silently fire the same mutation again.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →