Skip to content
Tutorials

How to Fix HTTP 429 Too Many Requests (2026)

HTTP 429 means the server is rate limiting you. Learn how to read Retry-After, back off correctly, and fix it in scrapers.

Rectangle Zenezen
October 9, 2026 4 min read
How to Fix HTTP 429 Too Many Requests (2026)
Click Here to Add Proxyon as a Trusted Source Add as a preferred source

Don't want to read?

Time is a precious resource, get the insights you need using your favorite AI chat.


What a 429 Too Many Requests Error Means

What a 429 Too Many Requests Error Means

A 429 is a client error defined in RFC 6585 for one situation: the client exceeded a rate limit. The spec leaves identification to the server. Most sites key the limit on your IP address, APIs count per token, and a WAF can count per cookie, header, or TLS fingerprint. A limit tied to your session cookie does not reset on a new IP.

A 429 is not a ban. A 403 blocks you outright and a 503 means the server itself is overloaded. A 429 clears once you slow down.


Read the Response Before You Retry

Read the Response Before You Retry

The Retry-After header holds either a number of seconds or an HTTP date, so parse both. Many APIs also send X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset, but those names are a convention, not a standard. The IETF draft for RateLimit header fields defines RateLimit and RateLimit-Policy instead, and states that Retry-After wins when both are present.

ABAP
HTTP/1.1 429 Too Many Requests
Retry-After: 30
RateLimit-Policy: "default";q=100;w=60
RateLimit: "default";r=0;t=30

One thing worth knowing: on most services, requests that came back as 429 still count against your quota, so a tight retry loop pushes the reset further away.


How to Fix 429 Too Many Requests in Your Code

How to Fix 429 Too Many Requests in Your Code

Honor Retry-After first. When it is missing, use exponential backoff with jitter, cap the attempts, and cut concurrency per host until the 429s stop. In Python, the Retry class from urllib3 does all of this behind requests. The backoff_jitter option needs urllib3 2.0 or newer.

PYTHON
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

retry = Retry(
    total=5,
    status_forcelist=[429, 503],
    allowed_methods=["GET", "HEAD", "POST"],  # POST is not retried by default
    backoff_factor=1,       # 0s, 2s, 4s, 8s, 16s when Retry-After is absent
    backoff_jitter=1,       # adds up to 1s of randomness per wait
    backoff_max=60,
    respect_retry_after_header=True,
    raise_on_status=False,  # hand back the final 429 instead of raising
)

session = requests.Session()
session.mount("https://", HTTPAdapter(max_retries=retry))

response = session.get("https://api.example.com/items", timeout=15)
print(response.status_code, response.headers.get("Retry-After"))

Two details trip people up. The first retry fires immediately and backoff starts on the second, which Retry-After overrides anyway. POST is skipped by default because a retried write can duplicate data, so add it only for idempotent endpoints.

Also Read: How to Scrape at Scale: Concurrency, Retries & Proxy Management


How to Fix 429 Errors When Scraping

How to Fix 429 Errors When Scraping

Scraping limits are almost always keyed on your IP, so spread requests across many of them. Residential proxies give each request a different household IP, and datacenter proxies are the cheaper option on targets that only count per IP. Rotation does not lower your total rate, though. Ten IPs sending 600 requests a minute against a 60 per minute limit are all at the ceiling.

Pace per IP, not per scraper. Cap concurrency per host, add random delays, and retry through a fresh IP rather than the one that just got throttled. Proxyon's rotating endpoint handles that, since every new connection gets a new address.

PYTHON
proxies = {
    "http": "http://user:pass@rotating-host:port",   # from your Proxyon dashboard
    "https": "http://user:pass@rotating-host:port",
}
session.proxies.update(proxies)  # each retry now exits from a different IP

Cloudflare's rate limiting rules can key on a cookie, header, or ASN instead of the IP, and can treat a whole IPv6 /64 range as one client. If 429s continue after rotating, the counter is not on the IP.

Also Read: How to Rotate Proxies in Python Requests


Fixing 429 on Your Own Site or in a Browser

Fixing 429 on Your Own Site or in a Browser

If your own site returns the 429, hit the origin directly and bypass the CDN. If the error disappears, the limit lives in a WAF or Cloudflare rate limiting rule, so raise the threshold or exclude the path. If it persists, the origin is throttling: on WordPress, usually a plugin hammering admin-ajax.php, a cron job, or a login brute-force. Fix it fast, because Googlebot treats a 429 like a server error and slows its crawl.

In a browser, the same rules apply: your shared IP hit a limit, so wait out Retry-After, stop refreshing, and disable extensions that fire background requests.


FAQ Section

FAQ

How long does a 429 Too Many Requests error last?

As long as the server says. Retry-After gives the exact wait, usually seconds to a few minutes. Without it, most windows reset within a minute, but daily quotas reset once a day, and every retry that returns another 429 can extend the wait on services that count failed requests.

Does a VPN or proxy fix a 429 error?

Only if the limit is keyed on your IP address, and only until the new address crosses the same threshold. Limits tied to your account, API key, or session cookie follow you to the new IP.

Is a 429 the same as being banned?

No. A 429 is temporary and clears once the window resets. A ban usually shows up as a 403 with no Retry-After, and ignoring repeated 429s is one of the most common ways to earn one.

Should I retry a POST request after a 429?

Only if the endpoint is idempotent or supports an idempotency key. A 429 is normally rejected before the server processes anything, so a retry is usually safe, but urllib3 will not retry POST unless you add it to allowed_methods.


Final Thoughts

A 429 is the server handing you the exact instructions to get unblocked, so read the headers before you touch your retry logic. Honor Retry-After, back off with jitter when it is missing, cap your attempts, and lower concurrency per host. For scraping, rotate IPs to spread the load, but pace each IP as if it were the only one you had. A rotating pool from Proxyon handles the address side of that, and your throttling handles the rest.

Get back to building.

We'll handle the proxies.