CalcEngine All Calculators

Why you're getting a 429 Too Many Requests error

API & Backend

A 429 is the server telling you to slow down, not that your request was malformed. This page explains what it means, how to read the headers that come with it, and what to do next.

A 429 means the server has decided you have sent too many requests in some window and is refusing this one. It is rate limiting, not a fault in the request itself — the same request will usually succeed once you wait. The response may carry a Retry-After header saying when to try again, given either as a number of seconds or as an absolute date. You can also get a 429 while apparently under the published limit, because the specification lets every server decide for itself what it counts and who it counts it against.

What the server is actually counting

A 429 is defined in RFC 6585 §4, and the definition is deliberately thin: it says the status code "indicates that the user has sent too many requests in a given amount of time", and then explicitly declines to say more. In its own words, the specification "does not define how the origin server identifies the user, nor how it counts requests." That single sentence is the reason 429s are confusing in practice. Every part of the accounting is left to the server: — Who you are. The counter may be keyed on your API key, your account, your OAuth client, your session cookie, or just your source IP. Two of your services sharing one key share one budget. Two of your users behind one corporate NAT may share one budget too. — What counts as a request. The limit may be applied per endpoint, across the whole API, or shared among several servers. A read and a write may cost different amounts against the same budget. — What "a given amount of time" means. Fixed windows, sliding windows, and token buckets all produce different refusals from the same nominal "100 per minute", and the server does not have to tell you which it uses. One thing the specification is firm about: responses with a 429 must not be stored by a cache. If you are seeing a 429 served repeatedly and instantly, with no variation, suspect an intermediary that is misbehaving rather than the origin.

Retry-After comes in two forms, and you must handle both

Most client code that handles Retry-After handles half of it. The field is defined in RFC 9110 §10.2.3 with this grammar: Retry-After = delay-seconds / HTTP-date Both forms are legal and you will meet both in the wild. Delay-seconds is a non-negative integer count of seconds to wait: Retry-After: 120 HTTP-date is an absolute timestamp. The format required for generating it is IMF-fixdate (RFC 9110 §5.6.7), which always ends in GMT: Retry-After: Sun, 06 Nov 1994 08:49:37 GMT Two things routinely go wrong here. The first is parsing: code that does parseInt(retryAfter) on a date string gets NaN, and code that treats NaN as zero retries immediately — which on most APIs extends the penalty rather than ending it. Branch on whether the value is all digits before deciding which parser to use. The second is clock skew. An absolute date is only as good as your machine's clock, and a client running a few minutes fast will retry early every time. The 429 response also carries a Date header holding the server's own view of now; compute the wait as the difference between the Retry-After date and that Date header, not against your local clock. Note also that recipients are expected to accept two obsolete date formats (rfc850-date and asctime-date) even though senders should no longer produce them, so a strict parser can still fail on a compliant-enough server.

X-RateLimit-Reset and the headers that are not standard

Alongside Retry-After you will often see a family of headers describing the budget itself — typically X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. These are conventions, not a standard. Nothing defines their units, so they differ between providers, and this is where integrations quietly break. X-RateLimit-Reset is the worst offender because it has at least three readings in common use: — a Unix timestamp in seconds, meaning "the window resets at this absolute moment" — a number of seconds remaining until the window resets — a Unix timestamp in milliseconds The values look similar enough that the wrong reading survives testing. A ten-digit number is almost certainly a Unix timestamp in seconds; a small number like 59 is almost certainly a duration. Rather than infer, check the provider's documentation once and pin the interpretation in your client — and prefer Retry-After when the response gives you both, since its units are actually specified. There is an IETF effort to standardise this area, draft-ietf-httpapi-ratelimit-headers, which defines RateLimit and RateLimit-Policy fields to replace the ad-hoc X-RateLimit-* set. It is an active Internet-Draft and has not been published as an RFC, so treat any RateLimit-* headers you receive today as provider-specific until that changes.

Why you can get a 429 while apparently under the limit

This is the case that sends people to search engines, and it is almost never a bug in the server. Common causes, roughly in order of how often they turn out to be the answer: — The counter is not yours alone. If the limit is keyed on IP, everything sharing your egress address shares your budget: other pods on the node, a NAT gateway, a CI runner pool, colleagues in the same office. Your service's own request rate can be well under the limit while the address's rate is not. — Burst versus sustained. A token bucket that permits 100 requests per second will still refuse 100 requests fired in the same 10 milliseconds if its burst capacity is smaller. Your average is fine; your instantaneous rate is not. — Fixed-window edges. With a fixed window, a burst at the end of one window and another at the start of the next are both legal individually, but they land within a few seconds of each other. Any sliding-window or per-second limit layered on top will reject the second burst. — More than one limit applies. Providers commonly enforce several simultaneously — per second, per minute, per day, plus a concurrency cap on in-flight requests. Staying under the per-second rate says nothing about the daily quota, and a concurrency cap can refuse you at a very low request rate if your requests are slow and overlapping. — Your retries are counted too. Requests that fail and are retried usually count against the budget. A retry storm after a blip can exhaust a limit that your steady-state traffic never approaches — which is why retries need backoff and jitter rather than a fixed delay. — The refusal came from somewhere else. A CDN, WAF, API gateway, or load balancer in front of the origin can issue its own 429 under its own policy, and its limits are usually neither documented alongside the API's nor reported in the API's own headers. — Distributed counters settle late. When a limit is enforced across several nodes sharing state, the count each node sees can briefly lag reality, so the effective limit near a boundary is fuzzier than the published number. The practical diagnostic: log the full response headers of the 429 itself, not just the status. The combination of which rate-limit headers are present, what Retry-After says, and whether a Via, Server, or CDN header names an intermediary will usually identify which of the above you are looking at within one incident.

Work out the request budget for a window

Once you know which limit applies to you, the next question is usually arithmetic: how many requests does a published rate actually buy over a given stretch of time? Enter the rate and the window to size a batch job, a sync, or a polling interval against it.

Last updated: August 2026

How to Calculate a Request Budget from a Rate Limit

429 Too Many Requests — how it works diagram

1. Enter your rate limit in requests per second (RPS). If your API publishes a per-minute or per-hour limit, divide by 60 or 3,600 to convert. 2. Enter the length of the window you care about. 3. Select the unit: seconds, minutes, or hours. 4. The calculator converts the window to seconds and multiplies by your RPS to give the total requests the limit allows across it. 5. Treat the result as a ceiling, not a target — it assumes one limit, evenly paced requests, and no retries.

Formula

Total Requests = Requests per Second (RPS) × Duration in Seconds

Duration conversions:
- Minutes → multiply by 60
- Hours   → multiply by 3,600

Useful conversions:
- 100 req/min = 100 ÷ 60 ≈ 1.67 RPS
- 1,000 req/hr = 1,000 ÷ 3,600 ≈ 0.28 RPS

This is the sustained-rate ceiling only. It does not model burst capacity,
concurrency caps, or a second limit applied over a longer period.

Worked Examples

Example 1 — Sizing an hourly sync against a 50 RPS limit

RPS: 50   Window: 1 hour = 3,600 seconds
Budget = 50 × 3,600 = 180,000 requests

The job needs 200,000 records at one request each:
200,000 ÷ 180,000 = 1.11 hours — it does not fit in the window.
Options: spread it over two hours, batch several records per request,
or move to a tier with a higher limit.

Example 2 — Reading a Retry-After you were given

Response:
  HTTP/1.1 429 Too Many Requests
  Date: Sun, 06 Nov 1994 08:49:07 GMT
  Retry-After: Sun, 06 Nov 1994 08:49:37 GMT

Wait = Retry-After − Date = 30 seconds.

Computed against the server Date header, the answer is 30 seconds on any
machine. Computed against a local clock running 5 minutes fast, the same
response yields a negative wait and the client retries instantly.

Example 3 — The failure case: under budget, still refused

Limit: 100 RPS   Window: 60 s   Budget = 100 × 60 = 6,000 requests
Sent: 4,000 requests in the minute — comfortably under budget.
Result: several hundred 429s.

The 4,000 were sent as four bursts of 1,000 in under a second each. The
sustained rate was 67 RPS; the instantaneous rate was ~1,000 RPS against a
bucket whose burst capacity was 200. The arithmetic above was never wrong —
it answers a different question than the one the server was asking.

Handling 429s in Client Code

Frequently Asked Questions

Does a 429 mean I have been banned? +
Usually not. A 429 is a temporary refusal and the same request typically succeeds after the wait. A ban is more often a 403. That said, some APIs lengthen the penalty when clients retry before the Retry-After deadline, so an ignored 429 can turn into a longer lockout.
What should I do if there is no Retry-After header? +
The header is optional — RFC 6585 says a 429 may include it. With no Retry-After and no rate-limit headers, fall back to exponential backoff with jitter: wait a second, then two, then four, up to a sensible cap, and stop after a fixed number of attempts rather than retrying forever.
Is X-RateLimit-Reset a timestamp or a countdown? +
It depends on the provider — the header is not standardised and both readings are in common use, along with milliseconds. A ten-digit value is almost certainly a Unix timestamp in seconds; a small value is almost certainly seconds remaining. Check the documentation once, and prefer Retry-After when both are present.
Why do I get 429s in my browser rather than from an API? +
The same mechanism applies to ordinary web traffic. A site, its CDN, or its WAF can rate-limit by IP, so repeated reloads, a shared office or VPN address, or an extension polling in the background can trip it. Waiting is the fix; the site owner controls the threshold.
Can I avoid 429s by spreading requests across several API keys? +
Sometimes, but check the terms first — many providers treat it as circumvention and key on the account rather than the key, so the limit does not actually change. Where a provider does allow it, the caveat is that limits keyed on IP are unaffected by adding keys.