Timeouts and retries¶
results = reqstorm.fetch_all_sync(
urls,
timeout=10, # seconds per attempt, including reading the body
retries=3, # retry right away, about 0.5 s, 1 s and 2 s apart
backoff=0.5, # the first wait, doubled after each retry
max_backoff=30, # never wait longer than this between two attempts
jitter=True, # spread the waits so retries do not arrive together
retry_rounds=2, # then resend what still failed, after everything else
retry_round_delay=30, # waiting 30 s before each round
)
Timeouts¶
timeout is the time allowed for one attempt, including reading the body (default 30 seconds). timeout=None turns it off. A slow server only fails its own requests; it never holds up the batch.
Immediate retries¶
With retries=N, a request is tried up to N more times right away. Between two attempts reqstorm waits, and the wait grows with each retry (exponential backoff). This applies both when a response comes back with a retryable status and when no response comes back at all (a timeout or a dropped connection).
| Retry | Wait without jitter (backoff=0.5, max_backoff=30) |
With jitter (default) |
|---|---|---|
| 1st | 0.5 s | 0.25–0.5 s |
| 2nd | 1 s | 0.5–1 s |
| 3rd | 2 s | 1–2 s |
| 4th | 4 s | 2–4 s |
| 5th | 8 s | 4–8 s |
| 6th | 16 s | 8–16 s |
| 7th and later | 30 s (max_backoff) |
15–30 s |
backoffis the first wait in seconds; it doubles after each retry.backoff=0retries without waiting.max_backoffcaps the wait (default 30 seconds). Without a cap,retries=10would wait 256 seconds before the last attempt.jitter(on by default) waits a random time between half and all of the computed delay. When a server has a hiccup, thousands of requests fail at the same moment; without jitter they would all retry at the same moment too, and hit the server again together.jitter=Falsewaits exactly.Retry-After: when the server sends this header (in seconds, up to 60), that wait is used instead, exactly as given.max_backoffand jitter do not apply to it, because the server said when to come back.
The waits come on top of the attempts themselves: with timeout=10 and retries=3, a server that never answers costs at most 4 × 10 s of attempts plus about 3.5 s of waiting.
Retry rounds¶
Some failures are temporary: an API that is briefly overloaded, or a rate limit you hit anyway. With retry_rounds=N, requests that still failed for a retryable reason are held back and sent again after the rest of the batch has finished, up to N more rounds, each after retry_round_delay seconds. Each request still produces exactly one result, with every attempt in its history.
What is retried¶
| Retried | Not retried |
|---|---|
| Connection errors and dropped connections | Invalid URLs |
| Timeouts | 4xx statuses such as 400, 401, 403, 404 |
Statuses in retry_statuses (default 429, 500, 502, 503, 504) |
Other statuses |
Change retry_statuses to retry other statuses, for example retry_statuses=(429, 503).