Skip to content

API retry and backoff simulator

See in advance how long a client waits when an API call returns 429 or 503. Enter your delay settings; with deterministic seeded jitter you get the time of every attempt, the total wait and the distribution over many runs. The calculation never leaves your device.

Free tool · Integration

Preset

Jitter type

The calculation runs in your browser; no value is sent to a server.

Total wait (this seed)
25.47 s
Total wait without jitter
51 s
Mean total wait
25.06 s
95th percentile total wait
39.4 s
Longest total wait
45.37 s

The last three values come from 500 consecutive seeds starting at this one.

Timeline

051 s · cumulative wait12345678Without jitterSelected jitter

Attempt table

Attempt table
RetryCeilingWaitCumulative
1200 ms120 ms120 ms
2400 ms179 ms299 ms
3800 ms682 ms981 ms
41.6 s1.07 s2.05 s
53.2 s559 ms2.61 s
66.4 s3.37 s5.98 s
712.8 s3.5 s9.48 s
825.6 s15.99 s25.47 s

Pseudocode

for attempt in 0..7:
  exp = min(30000, 200 * 2 ** attempt)
  delay = random(0, exp)
  sleep(delay)

In practice

  • On 429 (Too Many Requests) and 503 (Service Unavailable) the server may send a Retry-After header (seconds or an HTTP date). If it is present, do not go below your own calculation: wait = max(calculated, Retry-After). Without the header, the backoff is your responsibility.
  • Retrying is only safe for requests that are harmless to repeat. GET, PUT and DELETE are idempotent by definition; POST is not. If you retry a POST such as a payment or an order you risk a double transaction: send an Idempotency-Key header and make sure the server really supports the key.
  • Without jitter thousands of clients retry at the same moment (thundering herd) and knock the recovering service over again. Full or equal jitter spreads that load in time; also limit the total number and duration of retries and do not retry permanent errors (4xx other than 429) at all.

ceiling(n) = min(cap, initial × multiplier^(n−1)) · full: U(0, ceiling) · equal: ceiling/2 + U(0, ceiling/2) · decorrelated: min(cap, U(initial, previous × 3))

This tool only calculates waiting times; it sends no requests and does not measure network or server behaviour. Real delays also depend on request duration, timeouts and the settings of your client library. Results are illustrative.

Would you like to design retries, queues and error handling for your integrations together? We can separate which calls are safe to repeat and where a queue is needed.

Request a call

01

How to use it

  1. A

    Enter the initial delay, multiplier, cap and number of retries, or pick one of the presets.

  2. B

    Choose the jitter type; the timeline shows the jittered waits (filled marks) next to the no-jitter reference (faint marks).

  3. C

    Review the total wait and the distribution over many runs; copy the pseudocode or the result and share it with your team. The same seed reproduces the result.

02

How exponential backoff works

After every failed attempt the client waits longer than after the previous one: initial × multiplier^(n−1). The wait stops growing at the cap. A short outage is bridged quickly with short attempts, and during a long outage the service is not drowned by retries.

Exponential backoff alone makes clients that failed together retry together. Jitter breaks that synchronisation: the clients' waits are spread randomly and the load is spread in time.

03

Four jitter types

Full jitter picks the wait at random between 0 and the ceiling; the mean wait is half the ceiling and load spreading is best. Equal jitter keeps half the ceiling fixed and randomises the other half, which guarantees a minimum wait. Decorrelated jitter ties every wait to the previous one and is independent of the multiplier.

The simulator lets you compare all of them with the same seed: keep the seed and change the type. A single run can mislead, so the mean, the 95th percentile and the maximum of the total wait are computed from 500 runs.

04

Calculation and assumptions

Waits are rounded to milliseconds. Randomness is derived from the seed with the mulberry32 generator, which is not cryptographic and is meant for simulation only. Your real client uses its own random source, so only the distribution is representative, not the individual values.

Request duration, timeouts and circuit breakers are not modelled: the total wait is just the sum of the waits. The real elapsed time also includes the duration of every attempt.

FAQ

Which jitter type should I choose?
Full or equal jitter is enough in most cases. When many clients hit the same resource, full jitter spreads the load best; choose equal jitter if you want a guaranteed minimum wait. Retrying without jitter is acceptable only for a single client under low load.
If there is a Retry-After header, can I ignore my calculation?
No. If the server announced a time, trying earlier is pointless; the wait must be at least Retry-After. If your calculated backoff is longer, use that. The header can be a number of seconds or an HTTP date; read both.
Which errors should be retried?
Transient ones: network drops and timeouts, 429, 502, 503, 504 and often 500. Client errors such as 400, 401, 403, 404 and 422 give the same result when retried; do not retry them. Always limit the number of retries and the total duration.
Is it safe to retry a POST request?
Not by itself. After a timeout the server may have completed the operation; sending it again creates a double order or payment. Send an Idempotency-Key header and verify that the server answers the same key with the same result.
What is the seed for?
The randomness is derived from the seed, not from a true random source; the same seed gives the same delays. That lets you share a scenario with a colleague and fix a test expectation. Do not fix the seed in a real client.

Let's make your integrations fault tolerant

We design retries, queues and idempotency together for CRM, ERP and third-party API connections. Let's talk through your current flow in a free discovery call.