Prompt
Design the retry delays for a flaky API:
backoffSchedule(retries, base, cap)→ array of delays:base × 2^attempt, each capped atcape.g.backoffSchedule(5, 100, 1000)→[100, 200, 400, 800, 1000]withJitter(schedule, rand)→ full jitter: each delay becomesrand() × delay(rand injected for testability; use Math.floor on the result)
Solution
Retry logic is where mobile engineers ship distributed-systems bugs without noticing. The interview question isn't "can you multiply by two" — it's whether you know why each of the three ingredients exists, because each one prevents a specific production incident.
- Exponential growth exists because the failure you're retrying against is usually load. Fixed-interval retries (every 2s, forever) hold constant pressure on a struggling server — backoff is the client voluntarily shedding load so the server can recover.
- The cap exists because 100ms doubled 10 times is 102 seconds — past a point, longer waits punish the user without helping the server. The cap is a product decision (how long will a user stare at a spinner?) wearing a technical costume.
- Jitter is the one candidates miss, and it's the senior differentiator: when a deploy drops 10,000 mobile clients at once, they all fail at t=0 and — without jitter — all retry at exactly t=100ms, t=300ms, t=700ms as a synchronized wave. That's a thundering herd: the retries are the outage. Full jitter (
rand() × delay) spreads the wave into noise. AWS's architecture blog made "full jitter" the standard answer.
- Injecting
randinstead of callingMath.random()inline is the testability move — the tests below only pass because randomness is a parameter. Same reason you inject clocks.
The mobile-specific layer worth adding: retries are only safe on idempotent operations. Retrying a GET is free; retrying a POST /payments needs an idempotency key. And on device you cap total retry time, because the user can walk into a tunnel — reachability listeners beat blind persistence.
Say it: "Exponential backoff sheds load, the cap bounds user-visible latency, and jitter breaks retry synchronization — without jitter, ten thousand clients retrying in lockstep are the second outage."