TOOL | Propagation & containment
How long to wait on a 429, and how many requests to keep in flight
Enter your rate limits, backoff settings and current load. The planner computes every wait in the schedule, the concurrency your quota allows, and the time a backlog takes to clear.
Enter a base delay, a multiplier and an attempt cap. The planner builds every wait under full and equal jitter, checks concurrency against RPM and TPM limits, and reports how long a queued backlog takes to drain. The mechanics come from our cascading-failure research; the lever table in our agent reliability study gates every schedule on a transient-fault rate. The retry optimizer answers whether to retry; this page answers how long to wait.
Showing your last valid result. Update the inputs above to recompute.
Schedule wait
7.50 s mean / 15.0 s worst
The total mean and worst-case wait across all 5 attempts. The quota supports 6 whole concurrent slots at 4.00 s per attempt.
- Expected wait to resolve When the success rate is zero this equals the total mean wait.
- 1.00 s
- Attempts per request
- 1.94
- Binding limit
- 100 attempts/min (TPM)
- Safe in-flight requests
- 6.67 attempts (6 whole slots)
- Completed throughput
- 51.6 completed req/min
- Backlog drain
- 166.7 min
If every attempt fails, the total mean wait is 7.50 s and the worst case (no jitter) is 15.0 s.
Each logical request costs an average of 1.94 attempts. 3.1% of requests exhaust the cap without resolving.
RPM allows 1,000 attempts/min and TPM allows 100; tokens per minute binds. The request limit is 10 times the binding limit.
At 4.00 s per attempt, the quota supports 6.67 concurrent attempts (6 whole slots).
Your planned 8 in flight implies 120 attempts/min, using 120.0% of the ceiling.
50 requests per minute resolve. The retry tax is 48.4%: for every resolved request, the schedule spends 2 attempts. Raise the per-attempt success rate to recover quota.
At 20 new requests/min arriving and 50 resolved/min leaving, the 5,000 queued requests clear in 166.7 min. A request that exhausts its attempt cap stays in the queue. Each caller in the queue waits at least 1.00 s for its own attempts. The backlog consumes 20,000,000 tokens at the current per-attempt cost.
Per-attempt schedule
Backoff schedule, full jitter, 5 attempts
| Attempt | Raw wait (s) | Min (s) | Mean (s) | Max (s) | Cumulative mean (s) |
|---|---|---|---|---|---|
| 1 | 1.00 | 0.00 | 0.50 | 1.00 | 0.50 |
| 2 | 2.00 | 0.00 | 1.00 | 2.00 | 1.50 |
| 3 | 4.00 | 0.00 | 2.00 | 4.00 | 3.50 |
| 4 | 8.00 | 0.00 | 4.00 | 8.00 | 7.50 |
The min, mean and max columns are the exact bounds of each wait’s distribution. Under full jitter, every mean is half the raw wait; under equal jitter, three quarters; under no jitter, all three columns match.
These figures are worked defaults. Replace every field with your own provider limits and backoff settings.
wait_i = min(cap, base · multiplier^i), drawn from U(0, wait_i) under full jitterHow?
How this is calculated
The schedule. The raw wait before attempt i + 1 is the base delay multiplied by the multiplier raised to i, or the cap, whichever is smaller. With no jitter every wait is exact. Full jitter draws uniformly between zero and the raw wait, making the mean exactly half. Equal jitter draws from the upper half, so the mean is three quarters of the raw. A fourth variant, decorrelated jitter, exists in the AWS backoff literature and draws each wait from a range that depends on the previous draw rather than on a fixed schedule; it is not computed here because its expected wait requires either an approximation or a seeded simulation, and every other number on this page reproduces by hand. The exponential backoff and jitter glossary entry sets out the variant definitions and names the AWS source.
Expected wait to resolve. The total schedule is the sum of every wait. In practice, a caller that succeeds early leaves the loop early: with success rate a, wait i is incurred only when the first i attempts all failed, with probability (1 - a)^i. The expected wait to resolve is the sum of each wait's mean weighted by that failure probability. When a is 1, the sum is zero. When a is 0, it equals the total mean wait: every attempt is used.
The attempt ceiling. The RPM limit caps attempts directly. The TPM limit caps them at the limit divided by the tokens per attempt. When both are present, the smaller ceiling binds and the other carries headroom. Every attempt, including retries, counts against the limit; a logical request that takes three attempts spends three attempts of the per-minute quota over its life, though it never holds more than one slot at once. That distinction is why a retry storm can drain a quota that looked adequate: the quota is denominated in attempts, and the retry multiplier turns one request into several.
Safe concurrency. The maximum requests in flight at any instant comes from Little's law: the attempt ceiling in attempts per minute, multiplied by the attempt latency in minutes. The result is in attempts. Each worker holds one request at a time, and that request's attempts run one after another: a worker never occupies two slots at once. The pool to set is the whole-slot figure. Retries do not raise the number of concurrent slots; they raise the share of per-minute quota spent on work that already failed, which is the retry tax. When the reader enters a planned concurrency, the implied attempt rate is 60 times that concurrency divided by the latency, and the page checks it against the ceiling.
Completed throughput. The limit meters attempts, and retries are attempts. The completed requests per minute is the attempt ceiling divided by the expected attempts per request. The retry tax is the share of the quota spent on retries: 1 minus 1 over the attempts-per-request figure. A schedule that demands three attempts per request loses two thirds of the quota to retries before a single request resolves. Backpressure from the provider is denominated in tokens per minute, so ten queued items can sit inside budget or far outside it depending on the per-attempt token cost.
Backlog drain. A request that exhausts the attempt cap finishes its attempts but does not leave the queue, so the drain runs at the resolved rate, not the full completed throughput. When a planned concurrency is entered, the drain runs at the lesser of the plan's implied attempt rate and the ceiling. The lever differs: below the ceiling, more concurrency raises the drain rate; at the ceiling, the quota or the success rate has to move. The net drain rate is the resolved rate minus the arrival rate of new requests. When the net rate is positive, the drain time is the backlog divided by it. When it is zero or negative, arrivals meet or exceed the resolved rate and the queue grows. The page reports the shortfall and the arrival rate the reader would need to reach. Each individual caller in the queue waits at least the expected-wait-to-resolve figure for its own retry loop; drain time is the queue-level figure, not the caller-level one.
What this page does not compute. It plans a schedule and sizes a quota. Whether a retry is worth making, and what it delivers, is the retry optimizer's question. Whether to trip a circuit breaker, and what a breaker saves, belongs to the breaker mode on that same page. Step and chain latency across an agent's steps belongs to the latency budget calculator, which takes a backoff as an input and prices the chain around it. End-to-end chain reliability belongs to the cascade reliability calculator. This page computes a planned schedule; proving the schedule worked is a lowered peak at the dependency, not a number this page can report.
Interval note. Every figure on this page is exact arithmetic on entered values. No confidence interval applies and none is shown. When the reader's attempt success rate was measured rather than assumed, bracket it from a count of successes in attempts using the pass-rate CI calculator.
Formula: wait_i = min(cap, base · multiplier^i), drawn from U(0, wait_i) under full jitter
Questions
What is the difference between this page and the retry optimizer?
The retry optimizer answers whether to retry at all, prices six delivery policies against each other, and tells you what a retry delivers in cost and outcome quality. This page takes the retry decision as given and answers how long each attempt should wait, how many requests your quota allows, and how long a 429 backlog takes to clear. The retry optimizer computes no delays and no jitter; this page computes no outcome costs and no policy comparison. Read them side by side.
Should I add jitter?
A fleet of callers that hit a rate limit at the same instant will retry at the same instant without jitter, producing an identical burst and a second round of 429s. Full jitter spreads retries uniformly across the wait window; equal jitter concentrates them in the upper half, which is more conservative but less effective at breaking the synchronization. The case for jitter is strongest when multiple callers share one rate-limited dependency and weakest when a single caller retries alone. The exponential backoff and jitter glossary entry covers the variant definitions.
Why does the page not compute decorrelated jitter?
Decorrelated jitter draws each wait from a range that depends on the previous draw, so its expected total cannot be written as a closed-form sum. Computing it would require either an approximation labeled as a result or a seeded simulation with a reproducibility contract. Every other number on this page reproduces by hand; a column that does not would be the exception.
Which limit should I enter if I only know one?
Enter whichever you have. The ceiling computes from RPM alone, TPM alone, or both. When both are present, the page names the binding one and reports the headroom on the other. When only one is entered, the ceiling comes from that limit and no binding comparison is possible.
How does backlog drain time relate to each caller's wait?
Drain time is a queue-level figure: how long until every queued request has been served. Each caller inside the queue still waits at least the expected-wait-to-resolve duration for its own retry loop. The two numbers answer different questions. A 10-minute drain with a 4-second expected wait means the queue clears in 10 minutes, but any individual caller's retry loop resolves in about 4 seconds once it reaches the front.
Why is the pool size in attempts, when I have requests?
A request's retry attempts run one after another on the same worker, so a worker never holds more than one attempt at any instant. The number of workers to run is the whole-slot figure the page prints (at the worked defaults, 6 whole slots). Retries spend quota per minute, which lowers the resolved throughput, but the number of concurrent slots stays the same.
About this tool