Server

429 Too Many Requests — Causes and How to Fix It

Updated 2026-08-31~10 min read

429 Too Many Requests means something counted your requests, decided there were too many, and stopped serving you. Nothing is broken — this is a system working exactly as designed, and the design is deliberately telling you to slow down.

The complication is that three different layers can produce it, and they look identical from the outside. Your own web server can rate-limit visitors. A CDN or WAF like Cloudflare can limit them before the request ever reaches you. And an external API your code calls can limit your server. Same status code, three completely different fixes.

So the useful first step is not fixing anything — it is working out which layer is counting.

Who is doing the limiting?

Identify the source before changing anything. The response itself usually tells you if you look at the headers rather than the page.

SourceHow to recognise itWhere the fix lives
CDN / WAF (e.g. Cloudflare)Branded error page, ray ID, cf- headersThe CDN dashboard — not your server
Your web serverPlain Nginx/Apache error page or your custom oneServer config (limit_req, mod_evasive)
Your applicationJSON body with your own error formatApplication code and its rate-limit rules
An upstream APIOnly your server-side calls fail; visitors are fineYour client code — add backoff and caching
💡 Run "curl -I" against the URL and read the headers. Cloudflare adds cf-ray; many APIs add X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. Those headers answer the "who and how many" question in one command.

Retry-After: the header that tells you what to do

A well-behaved 429 includes a Retry-After header, and it is the single most useful piece of information in the response.

It comes in two forms: a number of seconds to wait, or an HTTP date to wait until. Either way it is the server telling you exactly when it will start accepting requests again — which is far better than guessing.

If you are writing a client, read it and honour it. Retrying immediately after a 429 is the behaviour that gets IP addresses blocked outright rather than merely throttled, because from the server side it is indistinguishable from an attack.

If you are issuing 429s, send it. Without Retry-After, well-written clients have to guess, and badly written ones will hammer you continuously.

Common causes, most frequent first

  • Your code calls an API in a loop without pacing. Iterating over a few thousand records with one API call each will hit almost any rate limit within seconds.
  • No caching on repeated calls. Fetching the same exchange rate or product data on every page load multiplies your request count by your traffic.
  • Bot protection triggering on legitimate traffic. Cloudflare and similar tools sometimes classify a monitoring tool, a feed reader or an aggressive but honest crawler as abuse.
  • Shared IP address. On shared hosting or behind corporate NAT, you inherit the reputation and the request count of everyone else using that address.
  • wp-cron or similar polling on a busy site. WordPress fires cron on page views; on a high-traffic site that can mean hundreds of internal requests a minute.
  • A retry loop with no backoff. The first 429 triggers a retry, which triggers another 429, which triggers another retry — this turns a brief limit into a sustained block.
  • Login or form endpoints being brute-forced. Here the 429 is doing its job and the right response is to leave it alone.

If your code is being limited: back off properly

When you are the client, the correct behaviour is well established and worth implementing once, properly.

Use exponential backoff with jitter. Wait one second, then two, then four, then eight — and add a small random amount to each. The randomness matters: without it, every client that failed at the same moment retries at the same moment, producing a synchronised wave that keeps everyone limited.

Honour Retry-After when it is present. It overrides your own backoff calculation, because the server knows better than your algorithm does.

Cap the number of retries. Infinite retry loops turn a temporary limit into a permanent block and hide the underlying problem from you.

Cache aggressively. The cheapest request is the one you never make. Data that changes hourly does not need fetching on every page view, and a short cache often removes the rate-limit problem entirely.

Batch where the API supports it. One request for a hundred records beats a hundred requests for one record, and most APIs count requests rather than records.

💡 If you are consistently hitting limits even with proper backoff and caching, the honest answer is usually that you need a higher API tier — not a cleverer workaround. Trying to evade a rate limit by rotating addresses is likely to violate the provider's terms and get the account suspended.

If your visitors are getting 429

  • Check whether it is your server or your CDN. The error page tells you: a branded page with a ray ID is the CDN, a plain one is your server.
  • Review the actual request pattern in the access log before loosening anything. If the traffic really is abusive, the limit is working and should stay.
  • Look for false positives on good bots. Googlebot, uptime monitors and legitimate feed readers can trip aggressive rules — and rate-limiting Googlebot will cost you rankings.
  • Check your own site is not generating the load. Plugins that poll internal endpoints, or a misconfigured cron, can consume the entire limit before real visitors arrive.
  • Enable page caching before raising limits. Cached pages never reach the rate limiter at all, which fixes the cause rather than the symptom.
  • Set limits per endpoint rather than globally. Login and API endpoints deserve tight limits; static pages usually do not need any.

Why raising the limit is usually the wrong first move

The instinct when seeing 429 is to raise the threshold. Occasionally that is right, but more often it converts one problem into a worse one.

Rate limits exist to protect finite capacity. Raising them without adding capacity means the requests now reach your application, consume workers and memory, and you trade a clean 429 for a slow site or a 503 — a worse experience delivered more expensively.

The better sequence is: cache first, so most requests never reach the limiter; fix whatever is generating unnecessary load; then, if genuine demand still exceeds the limit, raise it and add the capacity to serve it.

The exception is a limit that was simply set too low for normal traffic. If your access log shows ordinary visitors browsing normally and hitting limits, that is a misconfiguration and raising it is the correct fix.

Want to set your own rate limits instead of inheriting someone else's?

Cloud NVMe VPS with a dedicated IP and full root access — configure caching and limits per endpoint. From ฿150/month.

Frequently Asked Questions

How long should I wait after a 429?

Read the Retry-After header — it tells you exactly. If it is absent, use exponential backoff with jitter: one second, then two, four, eight, each plus a small random amount. Never retry immediately; that is what turns a temporary throttle into an outright block.

Is 429 my fault or the server's?

Usually neither is broken. It means your request rate exceeded what the other side allows. Check whether your code is making unnecessary repeat calls that caching would eliminate; if the rate is genuinely required by your workload, you need a higher tier rather than a workaround.

Why do I get 429 when I have barely made any requests?

Most likely you share an IP address with others — shared hosting, corporate NAT, a VPN exit node — and the limit counts the address, not you. Testing from mobile data will confirm it quickly. Some limits are also per-account rather than per-IP, so check whether another process is using the same credentials.

Does 429 affect SEO?

It does if Googlebot receives it. Google treats 429 as a signal to slow down and will reduce crawl rate; if it persists, pages drop out of the index. Make sure your rate-limiting rules exempt verified search engine crawlers, and check the Crawl stats report in Search Console for a spike in these responses.