A rate limit is a contract about when a client may try again. The difficult part is not recognizing a 429 response. It is preventing every worker, tab and retry queue from turning one rejection into a larger burst.

Source review: October 29, 2026. Protocol references: RFC 6585 (April 2012), RFC 9110 (June 2022), and draft-ietf-httpapi-ratelimit-headers-11 (May 2026). The RateLimit fields document is still an Internet-Draft, not an RFC.

Read the response before choosing a delay

RFC 6585 defines 429 Too Many Requests for a client that has sent too many requests in a given period. The server may include Retry-After, but it does not have to. The specification also leaves the counting model to the server. A limit might apply to one credential, one resource, a whole account, or a cluster of servers.

That uncertainty matters. A client cannot infer a universal quota from the status code alone. It should keep the response body, request identity and any documented limit headers together so operators can see which boundary was reached.

Retry-After has two legal forms. RFC 9110 allows either an HTTP date or a non-negative number of seconds. Clients need to parse both. When the value is a date, clock skew can make a future deadline appear to have passed, so a small minimum delay is safer than an immediate retry.

Keep one retry budget

The clean design gives the original operation one shared retry budget. A web request, background worker and message consumer should not each create a new chain for the same operation.

Carry an operation identifier through the queue. Record the attempt number, the last status, the next eligible time and the reason for the delay. If a write can be retried, pair this with an idempotency key so the server can recognize the same intended operation. The companion guide on API idempotency explains why retry safety belongs to the operation, not to one network call.

A useful policy separates three cases:

  • A valid Retry-After sets the earliest next attempt.
  • A 429 without a usable delay uses capped exponential backoff with jitter.
  • A permanent validation or authorization error does not enter the rate-limit retry path.

Exponential backoff and jitter are client policies, not requirements in RFC 6585. Jitter is useful because identical clients often fail at the same moment. Adding a randomized interval spreads their next attempts instead of rebuilding the burst on a new timestamp.

Treat quota headers as guidance

The HTTPAPI working group is developing standard RateLimit-Policy and RateLimit fields. The May 2026 draft can describe a quota policy, the available quota and an effective window. It also says that a positive remaining value does not guarantee the next request will succeed. Other limits may still apply.

The draft gives Retry-After precedence when both are present. That is a useful implementation rule today, but the document remains an Internet-Draft and can change before publication. Clients should isolate parsing behind a small adapter and keep support for the provider’s documented fields.

Do not turn a quota estimate into a local authorization decision. A proxy or SDK can slow requests, but the origin server remains responsible for enforcing its policy.

Make concurrency part of the limit

A client can respect a per-second quota and still overload a service with too many simultaneous requests. Use a concurrency gate beside the time-based limiter. The gate should cover retries as well as first attempts.

For a worker pool, reserve capacity before sending the request and release it after the response is fully handled. For a queue, schedule the next eligible time instead of sleeping inside a worker. Sleeping holds capacity while doing no work and makes shutdown or replay harder to reason about.

Batch APIs need another boundary. A successful HTTP response can contain failed items, while a rejected batch may leave some server-side work uncertain. Batch API partial failures shows how per-item outcomes keep retries from repeating completed work.

Log the decision, not every secret

A useful rate-limit event records the service, operation type, quota scope when known, response status, parsed delay, chosen next-attempt time and attempt number. It should also record whether the delay came from Retry-After, a provider field or local backoff.

Do not copy credentials, full request bodies or personal data into the event. Link to a protected trace when deeper evidence is needed. Aggregated counts can then answer practical questions: which operation reaches the limit, how long clients wait, how many requests exhaust their retry budget, and whether one deployment increased concurrency.

Reporting & Sources