sfw/fix
429 medium

429 Too Many Requests

A client sent too many requests in a short window and the server is throttling it until the rate limit resets.

What you see

429 Too Many Requests
You have sent too many requests in a given amount of time.
Retry-After: 60

What’s actually happening

Requests that worked a minute ago start coming back as 429. It often hits one client or one IP while everyone else is fine, and it tends to clear on its own after a short wait. If a Retry-After header is present, the response usually says exactly how many seconds to hold off. Pages may half-load with broken images or failed XHR calls when an asset endpoint is the thing being limited.

Common causes

  • A plugin or cron job hammering an endpoint in a tight loop (WordPress wp-cron.php firing on every page load on a busy site is a classic).
  • An aggressive bot or scraper crawling from a single IP faster than the rate limiter allows.
  • A third-party API quota exceeded — your server is the client getting 429'd, and the failure surfaces inside your app.
  • A browser or JS refresh/retry loop re-firing the same request when it gets an error, which compounds the problem.
  • Shared hosting or a CDN (Cloudflare, etc.) enforcing a per-IP request ceiling that several users behind one NAT trip together.

How to fix it

  1. Read the Retry-After header and honor itOpen DevTools Network tab, click the 429 response, check the Retry-After value (seconds, or an HTTP date). Have your client back off for that long instead of retrying immediately. curl -sI https://example.com/path | grep -i retry-after shows it from the terminal.
  2. Find what's generating the volumeGrep the access log for the offending IP and path: sort | uniq -c | sort -rn on the request column. A single IP with thousands of hits to one URL points at a bot or a loop. For WordPress, disable wp-cron and run it from system cron: define('DISABLE_WP_CRON', true); in wp-config.php, then a real crontab entry hitting wp-cron.php once a minute.
  3. Add client-side backoff with jitterIf your own code calls an API, wrap retries in exponential backoff (1s, 2s, 4s) plus a random jitter so retries don't all fire at the same instant. Never retry a 429 in a tight while-loop.
  4. Raise or tune the limit if it's your own serverIn nginx, limit_req_zone / limit_req control this — check the rate= and burst= values. For Cloudflare, look at Security > WAF rate limiting rules. Whitelist known-good IPs (your monitoring, your office) so health checks don't get throttled.
  5. Cache to cut request volume at the sourcePut a page cache or CDN in front of dynamic endpoints so repeat hits never reach the rate-limited backend. Fewer origin requests means the limiter rarely trips.

Stop it recurring

Cache aggressively, move cron off page loads, and add backoff-with-jitter to any code that calls a rate-limited API.

Related errors