The Retry pattern re-attempts a failed operation to recover from transient issues, and the Backoff pattern adds increasing delays between those retries so the system doesn't overwhelm a struggling dependency.
Key Points: • Retry assumes many failures, like a brief network glitch or a momentary timeout, are transient and will succeed if attempted again shortly after. • Backoff increases the wait time between each retry attempt, commonly exponentially, instead of retrying immediately and repeatedly. • Adding jitter, a small random variation, to the backoff delay prevents many clients from retrying at exactly the same moment and creating a synchronized traffic spike. • A maximum retry count or maximum total wait time is important so a genuinely failing dependency doesn't cause requests to retry indefinitely. • Retry with backoff is typically combined with a circuit breaker, which stops retries altogether once failures indicate the dependency is down rather than just briefly struggling.
Example: A client calling a flaky downstream API might retry after 200ms, then 400ms, then 800ms if each attempt fails, giving the dependency progressively more breathing room to recover instead of hammering it with immediate, repeated requests.
Code Example:
int attempts = 0;
long delay = 200;
while (attempts < 3) {
try {
return client.call();
} catch (TransientException e) {
attempts++;
Thread.sleep(delay);
delay *= 2;
}
}
throw new RetriesExhaustedException();Interview Tip: A concise interview answer is:
"Retry re-attempts a failed call on the assumption the failure is transient, and backoff spaces those retries out, usually with exponential delay and jitter, so retries don't pile on load right when a dependency is struggling. I'd cap the retry count and pair it with a circuit breaker so a genuinely down dependency stops getting hit entirely."