translate/index.ts — 429 retries at 1s, 2s, 4s ignore Retry-After, retry budget exhausted in 7 seconds
Author: SirBrentonCreated May 8, 2026Updated May 8, 2026
Finding
calculateRetryDelay in packages/utils/src/translate/index.ts
uses pure exponential backoff on 429 responses.
Retry-After is never consulted.
RETRY_CONFIG = {
maxRetries: 3,
baseDelay: 1000ms,
backoffMultiplier: 2,
maxDelay: 10000ms
}429 and 5xx are handled identically.
What happens under rate limiting
When a translation provider returns 429 with
Retry-After: 60:
- Retry 1 fires at 1s — inside cooldown
- Retry 2 fires at 2s — inside cooldown
- Retry 3 fires at 4s — inside cooldown
- All three retries fail
- Retry budget exhausted in 7 seconds
- Provider said wait 60 seconds. Client didn't listen.
The consequence
On a 60-second provider cooldown, the entire retry budget is consumed in 7 seconds against requests that cannot succeed.
The correct behavior
On 429 with Retry-After:
- Read the header value
- Wait at least that duration before retrying
- Fall back to exponential backoff only when
Retry-Afteris absent
Related pattern
retry-after-ignored-under-concurrency
Corpus reference: https://github.com/SirBrenton/pitstop-truth
Source: refly-ai/refly