Skip to content
ThemesIonic — home
Troubleshooting

429 Too Many Requests on WordPress — Find the Rate Limiter Before You Touch It

A 429 is a rate limiter refusing a request. On a WordPress site it can come from the CDN, the web server, a security plugin, WordPress's own comment flood check, or a remote API your site calls. The response headers tell you which.

5 min read intermediate

A 429 Too Many Requests is a rate limiter saying no, and a WordPress site can have five of them: a CDN or firewall, the web server, a security plugin, WordPress's own comment flood check — or a remote API refusing your site. Each one is configured in a different place, so find which one answered before changing anything.

Incoming or outgoing?

Where you see it Direction Who refused
Visitors or you get a 429 page in the browser Incoming A layer in front of or inside your site
"You are posting comments too quickly. Slow down." Incoming WordPress core's comment flood check
The editor shows a failed save; the network panel shows 429 Incoming A limit on /wp-json/
An update fails with "Download failed." and "Too Many Requests" Outgoing The download server refused your site
A plugin reports an API error with 429 Outgoing The plugin's remote service

Incoming: read the headers

curl -sI https://example.com/wp-login.php

A CDN or cloud firewall adds its own headers and usually serves a branded block page. A plain response with your web server's Server: header means the origin answered. A plain grey-and-white WordPress error page (the wp_die() style, often titled "WordPress › Error" or "Comment Submission Failure") means PHP ran — a plugin or core. Note Retry-After if present; it tells you how long the block lasts.

Web server

nginx's limit_req module rejects excess requests with 503 unless limit_req_status 429; is set, so a 429 from nginx means someone configured it on purpose. Search the server config for limit_req_zone and check which locations it covers. A zone applied to location / throttles every page, images included.

Security plugin or firewall rules

Login lockouts, XML-RPC throttling and REST limits are typical. The plugin's log names the rule and the IP. Two cases trip legitimate users:

  • REST limits and the block editor. The editor sends many REST requests per minute. A limit meant for anonymous scraping makes saves fail with Publishing failed. Exempt logged-in users.
  • Shared IP addresses. Offices, schools and mobile carriers put many people behind one address. A per-IP limit treats them as one heavy client.

If the lockout hit you and wp-admin is unreachable, wait for the window in Retry-After, or rename the plugin's folder in wp-content/plugins over SFTP to deactivate it, log in, rename it back and reactivate it. Then add your address to its allowlist instead of loosening the rule for everyone. If the CDN is the one blocking you, the plugin was never involved — check the CDN's firewall events for your IP before touching WordPress.

Incoming: WordPress's comment flood check

Core rate-limits comments on its own. wp_check_comment_flood() looks up the last comment from the same author within the past hour and, through wp_throttle_comment_flood(), blocks a new one if it comes less than 15 seconds later. For logged-out commenters "the same author" means the same IP address or the same email; for logged-in users, the user ID or email. Administrators and moderators are never throttled.

Here is the trap. WordPress takes the commenter's IP from REMOTE_ADDR. Behind a CDN or reverse proxy that does not restore the real client address, REMOTE_ADDR is the proxy's IP, and every visitor shares it. Two different readers commenting within 15 seconds of each other — normal on a popular post — and the second one gets a 429. The symptom looks random and never reproduces for the admin, who is exempt.

The fix is at the server: restore the client IP from the proxy's header using nginx's real_ip module or Apache's mod_remoteip, trusting only the proxy's IP ranges. Copying X-Forwarded-For into REMOTE_ADDR in wp-config.php without checking the source lets anyone spoof their address. WordPress behind Cloudflare shows the trusted-ranges setup. You can confirm the problem first: if recent comments in wp_comments all carry the same comment_author_IP, the proxy address is being recorded.

To change the 15-second window rather than the IP handling, filter comment_flood_filter; to disable comments entirely, see turning off comments.

Outgoing: your site is the one throttled

When WordPress downloads an update, download_url() turns any non-200 response into an error carrying the response message, so a refused download reads "Download failed." followed by "Too Many Requests". Shared hosting puts many sites behind one outbound IP, and a busy neighbour can exhaust a provider's per-IP allowance. Wait for the window to pass and retry once; Download failed covers the other causes of the same message.

For plugins calling external APIs, the usual cause is polling too often: a cron event every minute, or a request on every page view. Cache responses with transients and honour Retry-After in your own code:

if ( get_transient( 'myplugin_api_backoff' ) ) {
    return;
}
$response = wp_remote_get( $url );
if ( 429 === wp_remote_retrieve_response_code( $response ) ) {
    $wait = (int) wp_remote_retrieve_header( $response, 'retry-after' );
    set_transient( 'myplugin_api_backoff', 1, max( 60, $wait ) );
    return;
}

Common mistakes

  • Disabling the security plugin to "fix" a 429 that the CDN is sending.
  • Raising a site-wide limit instead of exempting logged-in editors.
  • Trusting X-Forwarded-For from any client to fix comment flooding.
  • Retrying an update in a loop, which keeps the outbound IP blocked.

Verify

  • curl -sI on the affected URL returns 200 from a normal client.
  • New comments record distinct visitor IPs in wp_comments.
  • The editor saves without 429s in the network panel.
  • The limiter you adjusted still blocks the abuse it was built for — test a burst against wp-login.php with a security checklist in mind.

Frequently asked

Yes, in one place: the comment flood check. If the same IP address, logged-in user or email posts a second comment within 15 seconds, WordPress stops with 'You are posting comments too quickly. Slow down.' and status 429. Administrators and moderators are exempt.
The editor talks to the REST API constantly: autosaves, previews, media and block lookups. A rate limit on /wp-json/ set for anonymous traffic can be tripped by one busy editor, and the save then fails. Exempt logged-in users or raise the REST limit instead of removing it.
Check the Retry-After header in the response, which gives seconds or a date. If it is missing, the limiter's own documentation or settings define the window. Retrying immediately usually extends the block.

Related guides