Retries with exponential backoff

Networking Mid-level Kotlin 2.0+ API 24+ Reviewed By Best Latest Apps

Pick the fix

After an outage, every client retries at exactly 1, 2 and 4 seconds, and the server falls over again. Fix?

Options
Hint 1 of 1

Why do all clients arrive at the same moment?

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A Add random jitter to each backoff delay

Correct. Spreading retries prevents synchronised spikes.

Why not the others?
  • B Retry immediately so requests finish sooner. Makes the spike worse.
  • C Retry 10 times instead of 3. More load during the outage.
  • D Remove backoff and use a fixed 1 s delay. Still synchronised.

30-second answer

Retry only errors that can succeed later: timeouts, connection failures, 5xx and 429. Don't retry 4xx errors or non-idempotent requests like payments unless the server supports idempotency keys. Wait longer each time (exponential backoff: 1 s, 2 s, 4 s) with random jitter so thousands of clients don't retry together, and respect a Retry-After header.

Practise saying it · 30 s. No recording, just a timer

Explain retry with backoff.

Say your answer out loud, then check which of these points you covered:

  • Retry only transient errors
  • Exponential backoff with jitter
  • Cap attempts
  • Idempotency for writes
  • Respect Retry-After

Deep dive

Cap attempts (often 3) and the maximum delay.

For a Flow, retryWhen { cause, attempt -> } with delay implements it.

WorkManager has built-in exponential backoff for background work.

Show the user a retry button after automatic retries fail.

A retry helper Compile-checked · Kotlin 2.4.21
suspend fun <T> withRetry(times: Int = 3, block: suspend () -> T): T {
    var delayMs = 1_000L
    repeat(times - 1) {
        try { return block() } catch (e: java.io.IOException) { }
        delay(delayMs + kotlin.random.Random.nextLong(0, delayMs / 2))
        delayMs *= 2
    }
    return block()
}

Common mistakes

  • Retrying immediately in a tight loop.
  • Retrying POST requests that aren't idempotent.
  • Retrying 401 or 404.

Senior take & follow-ups

Say which errors to retry and why jitter matters.

Follow-up questions

Think of your answer first, then open the hint.

  1. What's jitter for?

    Show hint

    Spreading retries so clients don't hit the server at the same moment.

  2. How do you retry a payment safely?

    Show hint

    Send an idempotency key so the server ignores duplicates.

Compare on iOS: Retries with exponential backoff Same policy on both platforms.

Suggest a fix if something here is wrong or out of date.