Grow the delay by a constant factor each attempt, cap it, and give up after a set number of attempts; jitter randomizes each delay so clients that failed together do not retry together. The “full jitter” variant sleeps random(0, min(cap, base * 2 ** attempt)) (AWS Architecture Blog, Exponential Backoff and Jitter), and when a server sends Retry-After, you honor it instead of your own schedule (RFC 9110, section 10.2.3).
The fde-challenge-backend spec in Vercel’s vercel-solutions GitHub organization (repository created in July 2026; the file does not say it is an interview) treats HTTP 429 and HTTP 503 from a partner catalog API as transient, allows at most three attempts in total, and sends the event id as the . Source 1HTTP contractPublisherVercel (vercel-solutions on GitHub)Source typecompany website Retry timeouts, HTTP 429 and HTTP 503; don’t retry HTTP 400 or a validation error, and retry HTTP 401 only once, after refreshing an expired token. Retry a non-idempotent call only with an idempotency key, cap both attempts and total time, and test with a fake clock and a seeded random source.
Retries multiply across layers: 3 layers making 3 attempts each turn one request into 27 calls on the dependency that is already failing. Retry at one layer, cap retries with a budget (for example, retries under 10% of requests, as in Google SRE book, Handling Overload), and pass the caller’s remaining deadline down so no layer retries past it. Write the wrapper in the retry-with-jitter question.