Skip to course content
Free generative AI app course

Generative AI Application Development with Python

Unit 09.01: Backoff with jitter, and a retry ceiling

Backoff spaces the retries. Jitter stops every client retrying at the same instant.

Exponential, plus randomness, plus a ceiling

Three retries with doubling waits and per-attempt jitter.

The code shows the schedule.

BASE, MAX_ATTEMPTS = 0.5, 4
rng_values = [0.31, 0.72, 0.08]

print(f"{'attempt':>8} {'base wait':>10} {'jitter':>8} {'actual':>8}")
total = 0.0
for attempt in range(1, MAX_ATTEMPTS):
    base = BASE * (2 ** (attempt - 1))
    jitter = rng_values[attempt - 1]
    actual = base * (0.5 + jitter)
    total += actual
    print(f"{attempt:>8} {base:>10.2f} {jitter:>8.2f} {actual:>8.2f}")

print(f"\n{MAX_ATTEMPTS - 1} retries, {total:.2f}s of waiting, then give up")
print("jitter matters: without it, every client retries at the same instant")

# Exponential backoff spaces the retries; jitter stops a thousand clients
# hitting the provider simultaneously the moment a rate limit clears, which is
# how a brief limit becomes a sustained one.

Without jitter, a thousand clients rate-limited at the same moment all retry at exactly the same moment - turning a brief limit into a sustained one that you helped cause.

The ceiling matters as much. Three retries and a give-up is a bounded cost; an unbounded loop against a provider outage is not.

The mistake this prevents

The mistake is retrying without a ceiling because the failure is transient. Provider outages last longer than any retry budget, and an unbounded loop turns a fifteen-minute outage into a bill.

Takeaway

Exponential backoff with jitter and a hard retry ceiling. Jitter prevents synchronised retries, and the ceiling bounds the cost of a real outage.