---
title: "Exponential backoff"
url: https://proxy.wiki/glossary/exponential-backoff/
type: Glossary Term
author: "proxy.wiki editorial"
published: 2026-09-06
updated: 2026-09-06
site: proxy.wiki
topics: ["Proxy fundamentals"]
license: CC BY 4.0 — quote freely with attribution to https://proxy.wiki/
---

# Exponential backoff

> Exponential backoff is a retry policy in which the wait between attempts grows by a constant factor each time, usually doubling.

**Exponential backoff is a retry policy in which the wait between attempts grows by a constant factor each time, usually doubling.** It gives a congested or rate-limited resource an increasing amount of time to recover instead of adding load to it.

## The three parts

All three are required. Growth alone is not a backoff policy.

```
delay = base * factor ** attempt      # growth
delay = delay * (0.5 + random())      # jitter
delay = min(delay, ceiling)           # bound
if attempt >= max_attempts: give_up() # termination
```

Jitter matters more than people expect. Parallel workers that fail together will retry together, reproducing exactly the burst that caused the failure, and a synchronised retry storm looks identical to an attack from the receiving end.

## Where the idea comes from

TCP has done this since long before HTTP clients did. RFC 6298 specifies that the retransmission timer is doubled on each timeout, that it should be rounded up to at least one second, and that any maximum imposed must be at least 60 seconds. RFC 8961 generalises the requirements for time-based loss detection. Borrowing a policy that the transport layer already applies underneath you is a reasonable default.

## When backoff is the wrong tool

| Response | Correct reaction |
| --- | --- |
| 429, or 503 with [Retry-After](/glossary/retry-after/) | Wait as instructed, then back off |
| Connection reset or timeout | Back off; the cause may be transient |
| 403 | Change something. Repeating it unchanged will not succeed |
| A CAPTCHA interstitial | Not a rate problem. Retrying harder makes it worse |

An explicit `Retry-After` outranks your own calculation. Waiting less than the server asked is the most reliable way to convert a temporary limit into a durable block.

## Commonly confused with

Backoff is not a substitute for a correct request rate. If a steady-state rate is above what the target tolerates, backoff simply produces a slow oscillation around the limit and a poor [success rate](/glossary/success-rate/). Fix the rate, and see [rate limiting](/glossary/rate-limiting/) and [concurrency](/glossary/concurrency/) for the surrounding controls.

## Frequently asked questions

### Why is jitter necessary if the delay already grows?

Because growth alone keeps parallel workers synchronised. Twenty workers that failed at the same moment will wake at the same moment and recreate the burst that caused the failure. Randomising each delay spreads the retries out, which is often the difference between recovery and a self-sustaining retry storm.

### Should backoff replace a rate limit in my scraper?

No. Backoff reacts after a failure; a rate limit prevents one. Relying on backoff alone produces a slow oscillation around the target's threshold, with wasted requests on every upswing. Set a request rate you believe the target tolerates, and keep backoff for the exceptions.

### How many retries should I allow?

Enough to survive a transient fault, few enough that a persistent one is reported rather than hidden. The count matters less than having one at all: an uncapped retry loop turns a single failing target into an outage generator, and the same applies to an uncapped delay ceiling.

## Sources

1. [RFC 6298: computing TCP's retransmission timer, including doubling on timeout](https://www.rfc-editor.org/rfc/rfc6298.html)
2. [RFC 8961: requirements for time-based loss detection](https://www.rfc-editor.org/rfc/rfc8961.html)
