Key takeaways
- Header names are case-insensitive, but their value formats and scope remain provider-specific.
- Limit, remaining, reset, and Retry-After values only make sense when tied to the same response and quota bucket.
- Reset values can be timestamps, durations, HTTP dates, or provider-specific representations.
- Retry-After is an HTTP-standard instruction with delay-seconds and HTTP-date forms.
- The structured RateLimit and RateLimit-Policy fields are still an active Internet-Draft as of May 2026.
1. Read the fields as a set
A rate-limit field is not useful in isolation. Capture the HTTP status, response Date, endpoint family, credential or tenant scope, and the complete group of relevant fields from the same response. Those details tell you which work was counted and which clock should anchor a reset value.
HTTP field names are case-insensitive. Your HTTP library might expose X-RateLimit-Remaining, x-ratelimit-remaining, or a normalized map key. Normalize names for lookup, but retain the original value and response context for diagnostics.
HTTP/1.1 200 OK
Date: Mon, 13 Jul 2026 09:00:00 GMT
X-RateLimit-Limit: 5000
X-RateLimit-Remaining: 137
X-RateLimit-Reset: 1783933260
X-RateLimit-Resource: core 2. Understand the common roles
A limit field usually describes the maximum quota for a provider-defined window or bucket. A remaining field reports capacity available at the time of the response. A used field can report consumed quota. A reset field identifies when capacity changes or replenishes. These meanings are common patterns, not one universal wire format.
The X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset names are widely recognizable conventions. Providers can assign different scopes and reset representations to them. Some providers publish separate dimensions for requests, tokens, endpoints, projects, or complexity instead of one request counter.
- Limit: the documented allowance for the applicable bucket or dimension.
- Remaining: the capacity reported as available after or around this response.
- Used: the amount already charged in the current provider-defined period.
- Reset: an absolute time or relative duration, depending on the provider contract.
- Resource, scope, or bucket: context that identifies which counter was charged.
3. Reset values use different clocks and formats
Do not infer a reset format from the word reset alone. GitHub documents X-RateLimit-Reset as UTC epoch seconds. Linear documents reset fields in epoch milliseconds. Discord provides X-RateLimit-Reset-After as seconds until reset and allows decimal precision. Anthropic reset fields use RFC 3339 timestamps, while OpenAI reset fields use durations.
Parse the format named by the provider documentation. When an absolute time is involved, use the response Date header as a useful reference for clock skew. When waiting for an elapsed duration, prefer a monotonic clock after you calculate the delay. Reject malformed, negative, or unreasonable values according to an explicit local policy.
# Different formats, not interchangeable
X-RateLimit-Reset: 1783933260
X-RateLimit-Requests-Reset: 1783933260000
X-RateLimit-Reset-After: 1.25
Anthropic-RateLimit-Requests-Reset: 2026-07-13T09:01:00Z
X-RateLimit-Reset-Requests: 1m30s 4. Treat Retry-After as a separate instruction
RFC 9110 defines Retry-After as either a non-negative integer number of delay seconds or an HTTP date. It tells a client how long it ought to wait before a follow-up request. Provider documentation can narrow when the field appears or how a particular API uses it.
If a valid Retry-After field accompanies a rate-limit response, do not retry earlier. A local backoff policy can choose a longer delay. The current IETF RateLimit draft also gives Retry-After precedence when both Retry-After and RateLimit are present.
Retry-After: 120
# Or an HTTP date
Retry-After: Mon, 13 Jul 2026 09:02:00 GMT 5. Identify the quota scope
The same account can have several limits at once. GitHub identifies a charged resource and separately enforces secondary limits. Discord associates routes with opaque bucket identifiers and distinguishes user, shared, and global scopes. Anthropic exposes request and token dimensions. OpenAI can expose request, token, and project-token dimensions.
A common header name does not identify the provider, and matching limit and remaining values can still describe different buckets if they came from different responses. Keep observations response-bound and provider-aware.
- Credential, user, IP address, workspace, organization, or project
- Route, endpoint family, model, resource, or operation type
- Request count, token count, bytes, complexity, concurrency, or another quota unit
- Primary window, burst policy, secondary control, or abuse protection
6. Recognize the current structured RateLimit draft
The May 2026 IETF draft defines RateLimit-Policy for quota policy information and RateLimit for current service-limit information. The fields use HTTP Structured Fields. A policy item can name a quota with q and a window in seconds with w. A service-limit item can report available quota with r and an effective window with t.
This syntax is still an active Internet-Draft, so implementations must track the draft version. It is also distinct from older individual names such as RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset that some providers document for their own APIs.
RateLimit-Policy: "permin";q=50;w=60
RateLimit: "permin";r=12;t=20 7. Normalize without discarding evidence
A useful client can translate documented fields into a small internal observation while retaining the raw rate-limit fields. Keep unknown values available for diagnostics, but never log credentials, cookies, response bodies, or unrelated sensitive headers with them.
Treat a normalized record as an observation, not a guarantee. Provider behavior can be dynamic, headers might be omitted on later responses, and another undisclosed control can reject the next request.
observation = {
provider, captured_at, status, endpoint_family,
scope, dimension, limit, remaining, reset_at,
retry_not_before, raw_rate_limit_fields
} 8. Turn observations into safe behavior
Use remaining capacity and reset information to pace optional work before exhaustion. When a response says to wait, stop the affected bucket rather than freezing unrelated traffic. Queue deferrable work, cap concurrency, and reserve retries for operations that are safe to repeat.
A positive remaining value does not guarantee the next request will succeed. Secondary limits, concurrency controls, dynamic capacity, resource locks, and abuse protections can act independently of the visible counter.
- Honor a valid Retry-After value before local retry timing.
- Apply bounded backoff and jitter when provider guidance is absent or allows it.
- Track each quota dimension separately instead of collapsing everything into requests per minute.
- Alert on sustained exhaustion, growing queue age, and repeated final failures.
Implementation checklist
- Capture the status, Date, endpoint context, and rate-limit fields from one response.
- Normalize field names case-insensitively.
- Select parsers from current provider documentation, not from header names alone.
- Keep separate request, token, resource, route, and project dimensions.
- Validate timestamps and durations before using them for scheduling.
- Give Retry-After precedence when applicable.
- Ignore malformed structured fields and continue with a safe local policy.
- Preserve raw rate-limit evidence without logging secrets.
- Recheck official documentation when a field appears, disappears, or changes format.
Sources and further reading
- RFC 9110, Retry-After RFC Editor
- RateLimit header fields for HTTP, draft 11 IETF Datatracker
- Rate limits for the REST API GitHub Docs
- Rate Limits Discord Developer Documentation
- Rate limits Claude Platform Docs
- API Overview OpenAI API Reference