API Reliability
HTTP 429 Too Many Requests: Rate Limits and Retry-After
Handle HTTP 429 responses correctly by reading Retry-After, controlling concurrency, adding jitter, and observing rate-limit behavior.
In this article
HTTP 429 Too Many Requests: Rate Limits and Retry-After
An HTTP 429 response means a client sent more requests than the service currently allows. The limit may apply to an IP address, user, token, tenant, endpoint, or shared service capacity. Treating every 429 as a generic server failure can create a retry loop that makes the overload worse.
A reliable client slows down, respects server guidance, and coordinates concurrent workers. A reliable server explains the limit consistently and protects critical operations from noisy consumers.
What the problem means
The Retry-After response header may tell a client how long to wait. Its value can be a number of seconds or an HTTP date, so clients should support both forms and cap unreasonable delays. Some APIs also publish remaining-quota and reset headers, but names and semantics vary; follow the specific contract instead of guessing.
Core design principles
Respect explicit server guidance
If Retry-After is present and valid, use it as the minimum delay unless application policy requires an even longer pause.
Control concurrency before retrying
Ten workers independently retrying can recreate the same burst. Use a shared limiter, queue, or token bucket to coordinate callers.
Add randomized jitter
Identical exponential schedules cause synchronized retry waves. Randomness spreads attempts over time and reduces collision.
Protect user experience
Background synchronization can wait; an interactive request may need a clear message, cached data, or a smaller operation.
Step-by-step workflow
- Inspect the complete response. Record status, headers, endpoint, method, token identity, request ID, and response body without storing secrets.
- Parse Retry-After safely. Accept seconds or an HTTP date, reject invalid values, and apply configured minimum and maximum delays.
- Apply bounded backoff. Increase delays after repeated failures, add jitter, and stop after a maximum attempt count or overall deadline.
- Reduce request volume. Batch work, cache stable responses, remove polling, deduplicate identical requests, and lower parallelism.
- Separate quota classes. Do not let optional analytics exhaust the same client budget needed for login, payment, or health operations.
- Monitor by identity. Chart 429 rate, retry count, queue depth, latency, endpoint, customer, and credential so one tenant does not hide inside a global average.
Practical example
A worker receives 429 with Retry-After: 30. It pauses that API identity, keeps unrelated providers running, and schedules the next attempt after at least 30 seconds plus jitter. If the job deadline would be exceeded, it records a recoverable failure rather than retrying indefinitely. The queue exposes delay to operators.
How to test the control
Test this workflow in a controlled environment before relying on it during a real incident. Begin with “Inspect the complete response” and create three cases: an expected success, a safe rejection, and a degraded or unavailable dependency. Continue through “Parse Retry-After safely” and “Apply bounded backoff,” recording the observed status, timestamps, logs, and operator decision. Repeat the test after a material configuration, provider, dependency, or permission change. A control is operational only when another team member can follow the documented process and obtain the expected result without hidden knowledge.
Metrics and review cadence
Measure both completion and outcome. For this topic, track evidence that “429 is handled separately from 500 errors,” “Retry-After supports both formats,” and “Backoff has jitter and a cap” remain true, then pair those checks with operational signals such as failures, denied actions, recovery time, unexpected destinations, retry volume, or stale ownership as appropriate. Review trends instead of celebrating a one-time pass. A rising exception count can show that the workflow is too difficult, while zero alerts may mean the detection path is not working.
Operating this in production
Reliability improves when clients and servers share an explicit contract. Document status codes, timeouts, retry rules, identifiers, and error bodies. Measure behavior at boundaries rather than assuming a successful function call means the complete user operation succeeded. Review the workflow after incidents, architecture changes, new integrations, and meaningful traffic growth. Assign an owner and measure whether the control works instead of recording only that it exists.
Common mistakes
- Retrying immediately in a tight loop.
- Ignoring Retry-After.
- Letting every worker manage limits independently.
- Retrying non-idempotent writes without safeguards.
- Hiding persistent quota exhaustion behind unlimited retries.
Duck Cloud tools for the workflow
Look up 429 in the HTTP Status Code Lookup, inspect live rate-limit and Retry-After headers with the HTTP Header Checker, and verify endpoint behavior with the Website Status Checker.
Review checklist
- [ ] 429 is handled separately from 500 errors
- [ ] Retry-After supports both formats
- [ ] Backoff has jitter and a cap
- [ ] Concurrency is coordinated
- [ ] Writes are safe to retry
- [ ] A total deadline stops attempts
- [ ] Metrics identify the limited identity
- [ ] Users receive a clear degraded response
Conclusion
HTTP 429 Too Many Requests is most effective when it becomes a repeatable engineering habit. Start with the highest-impact boundary, document the expected behavior, test realistic failure cases, and keep evidence that the control works. Small, verified safeguards compound into a system that is easier to operate and safer to change.