A 429 Too Many Requests is the only status code that is about you rather than about the server or the thing you asked for. Nothing broke, nothing is missing, and you are allowed to be here. You have simply asked more often than somebody decided was reasonable, and the answer is a refusal with a clock attached to it.

Everything else in the 4xx range describes a single request: this one was malformed, this one had no credentials, this one named nothing. A 429 describes a pattern. It is the server talking about your behaviour over a window of time, which is why it can arrive in response to a request that is perfectly correct and would have worked ten minutes ago.

The one error where trying again makes it worse

Most errors reward a retry. A 503 often clears on the second attempt, and a 500 is worth one reload in case you hit a bad moment. The instinct is usually right, and here it is exactly wrong.

A rate limiter counts requests. A retry is a request. Hammering a service that has just told you to slow down extends the window you are being held in, and on services that escalate, it turns a sixty-second limit into an hour or a block that needs somebody to lift by hand. The naive retry loop, the one with no delay in it, is how a brief throttle becomes an outage that looks like the other side’s fault.

So a 429 is the error where doing nothing is the active choice. Wait out the window, then go again, once.

The headers that say when to come back

A 429 usually carries Retry-After, giving either a number of seconds or a date:

HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1789412400

Retry-After is the standard one and the only one you can rely on. The X-RateLimit-* family is a convention rather than a specification: widely used, spelled differently by different services, and worth reading when it is there because it tells you the shape of the limit rather than just the next moment you may knock.

Those headers are the difference between backing off correctly and guessing. If you are writing anything that talks to an API on a schedule, read them: a service that said sixty seconds and gets a retry every second is being asked one hundred and twenty times to serve requests it has already declined.

When the traffic was not yours

The awkward part of a 429 is that the thing being counted is rarely a person. It is an IP address, an API key, an account, or a session, and each of those covers more than one of you.

An office behind a single address, a coffee shop, a mobile carrier doing carrier-grade NAT, a CI pipeline sharing a key with a team, a colleague testing a script against the same endpoint on the same credentials. All of those produce a 429 for somebody who did nothing unusual, and none of them are visible from the error page.

Which gives you the useful test. If a 429 follows you across networks it is your account or your key, and if it disappears on mobile data it was the address you were coming from. That is the same question as telling your bug from their outage, asked about a limit instead of a failure.

You can be rate limited without ever seeing a 429

Nothing obliges a service to use this code. Plenty return a 403 to make throttling look like a permissions decision, some return a 503 because from the outside “not now” is true either way, and a CDN in front of an application will often answer with its own choice rather than the application’s.

So a 429 is good news of a sort: it is a service being specific with you. The absence of one is not evidence that you are not being limited, and if a 403 or a 503 appears only under load and only from one address, a limiter is the thing to suspect regardless of what the code says.

If it is your API

The question worth answering before any of the tuning is which layer is counting. A limit in your application, one in nginx, and one at the CDN are three different sets of numbers, and the one your users are hitting is usually not the one you have been looking at.

Then send the headers. A 429 with no Retry-After is a service refusing to say when, which leaves every client to invent a backoff, and the ones they invent are worse than the number you would have given them. It costs nothing to be specific.

And be careful what the limit counts. Per-IP limits punish offices and shared networks for the behaviour of one person on them, which is a support ticket that arrives as “your site is broken for our whole team”. Per-account or per-key limits are harder to implement and much easier to explain.

Why a 429 is hard to reconstruct afterwards

By the time somebody tells you about it, the window has passed and the request works. What made it fail was not the request but its company: the other ninety-nine that arrived in the same minute, most of them from somebody else, none of them in front of you now.

Session Replay

Free Chrome extension. One click on the page that is misbehaving captures the screenshot, the console and the network log, and hands you a link to paste into the ticket.

Get the extension

The network log is what makes a 429 investigable at all: the failing request, the exact minute, and the response headers saying which limit was hit and how long it had to run. That is the difference between a report somebody can match against a rate-limiter log and a message saying the site stopped working for a bit this morning.

In one paragraph

A 429 Too Many Requests means you have asked too often, which makes it the only status code about your behaviour rather than about the server or the resource. It is also the one error where retrying is actively counterproductive, because a retry is another request for the limiter to count: read Retry-After, wait, then go once. The traffic being counted is frequently not yours, since limits apply to addresses and keys that cover whole offices and teams, and a phone on mobile data will tell you which of the two you are dealing with. If it is your API, work out which layer is counting, always send Retry-After, and prefer limiting a key over an address so that one person cannot lock out a building.