Guides 5 min read

429 Too Many Requests: Rate Limits, Retry-After and Backoff

A 429 means a client sent too many requests in too short a time. How rate limits work, what Retry-After says, how to back off, and why an uptime monitor can hit one.

429 Too Many Requests means the server is rate limiting you: the client has sent more requests in a period than the server allows, and it should wait before trying again. Nothing is broken, and repeating the request at once makes it worse. A well-behaved server says how long to wait in a Retry-After header; a well-behaved client waits at least that long, and without one backs off with growing delays. When a monitor hits a 429, the usual fix is to exempt the monitor from the limit or check an endpoint without one.

How rate limiting works

RFC 6585 defines 429 but leaves the rules to each server. A limit has three parts:

  • Who is counted: an IP address, an API key, a user account, or a combination. Limits by IP count everyone behind the same address together.
  • What is counted: all requests, or only some, such as logins, searches or a costly API endpoint, often with a stricter limit.
  • How time is counted: a fixed window resets on the minute; a sliding window looks at the last 60 seconds; a token bucket refills at a steady rate and allows short bursts up to its size.

The response often tells you where you stand:

HTTP/2 429
retry-after: 30
x-ratelimit-limit: 100
x-ratelimit-remaining: 0
x-ratelimit-reset: 1793091600

Retry-After is standard and is either a number of seconds or an HTTP date. The X-RateLimit-* headers are a common convention rather than a standard, and their meaning varies: reset may be a Unix time or a number of seconds, so read the API’s documentation. An IETF draft defines standard RateLimit and RateLimit-Policy fields, which some APIs have started to send.

Where 429s come from

  • Third-party APIs you call, such as payment, email, maps or chat services, which limit each key or account.
  • Your own API gateway or framework, through rate limiting middleware.
  • Your web server. nginx’s limit_req answers 503 by default; set limit_req_status 429 so clients know to slow down rather than assume an outage.
  • CDNs and WAFs, through rate limiting rules. Depending on the rule, the answer is a 429, a 403 or a challenge page.
  • Login and form protection in a CMS or security plugin, which limits attempts per address.

Handling a 429 as a client

  • Honor Retry-After. Wait at least as long as it says. Retrying sooner usually gets another 429 and can extend a block.
  • Back off exponentially, with jitter. Without Retry-After, wait longer after each failure, for example 1, 2, 4 and 8 seconds, plus a random part, so many clients don’t retry at the same moment.
  • Cap the retries. After a few attempts, give up and report the error, or put the work in a queue for later.
  • Send fewer requests. Cache answers, use batch endpoints, ask for larger pages, and use webhooks instead of polling where the API has them.
  • Spread scheduled work. Cron jobs that all start on the hour hit limits together; offset them by a few minutes. The guide to cron expressions shows how.
async function fetchWithBackoff(url, options = {}, attempts = 5) {
  for (let attempt = 0; attempt < attempts; attempt++) {
    const response = await fetch(url, options);
    if (response.status !== 429) return response;
    const retryAfter = Number(response.headers.get('retry-after'));
    const wait = retryAfter > 0 ? retryAfter * 1000 : 2 ** attempt * 1000 + Math.random() * 1000;
    await new Promise((resolve) => setTimeout(resolve, wait));
  }
  throw new Error('Still rate limited after ' + attempts + ' attempts');
}

This sketch only reads Retry-After as seconds; production code should also accept the date form.

Setting rate limits on your own site

  • Answer 429, not 503 or 403. A 503 looks like an outage and a 403 like a permanent refusal; a 429 tells clients and monitoring tools exactly what happened.
  • Send Retry-After, so clients don’t have to guess.
  • Limit by key or account where you can. Limits by IP punish offices, schools and mobile networks where many people share one address.
  • Allow bursts. A page load can make dozens of requests at once; a token bucket with room for a burst avoids blocking normal visitors.
  • Exempt your monitoring, or give it its own health check endpoint without a limit.
# nginx: 10 requests a second per address, bursts of 20, answered with 429
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

server {
    location /api/ {
        limit_req zone=api burst=20 nodelay;
        limit_req_status 429;
    }
}

Why an uptime monitor can hit a 429

One check a minute sounds harmless, but it adds up in ways that are easy to miss:

  • Several monitors on one host. Ten monitors on the same API, each checking every minute, are ten requests a minute from the same client, plus the confirming re-checks when something fails.
  • Strict limits on the checked path. Login pages, search and form endpoints often allow only a few requests a minute per address.
  • Shared addresses. A monitoring service’s checks come from a few known addresses. A limit by IP counts every check from that address together, including other users’ checks of the same public site or API.
  • A bot rule that rate limits. Some firewalls count automated clients separately and limit them harder than browsers.

What to do, in order: exempt the monitor from the limit by its IP addresses, monitor a health endpoint that has no limit, check less often, or combine monitors that hit the same API. Don’t accept 429 as up across the board, since a limit that starts blocking your real users is worth knowing about. HTTP status codes in monitoring covers which codes to treat as failures, and the API monitoring checklist what else to watch on an API.

429s and Uptimecheck

In Uptimecheck uptime monitoring and API monitoring, a 429 is outside the default expected statuses (200 to 399), so it counts as down once a second check confirms it. When the server answers a plain 429, the incident says that our checks are rate limited, quotes the Retry-After value when the server sent one, and suggests exempting requests whose user agent contains “Uptimecheck”, checking less often or using an endpoint without the limit. Checks run from Stockholm, Sweden; how to allow Uptimecheck through a firewall lists the addresses to exempt, with rules for Cloudflare, including its rate limiting rules, and for nginx. You choose each monitor’s interval, from every minute to every hour.

Uptimecheck follows the same rules when it sends your alerts. If Slack, Microsoft Teams, Discord or PagerDuty answers 429, the alert is retried after 30 seconds, 2 minutes, 10 minutes and 30 minutes, and never sooner than the service’s Retry-After asks, up to an hour. See why alerts may not arrive for what happens when a channel keeps failing.

Tell a rate limit from an outage. Try Uptimecheck free for 14 days, no credit card required.

Questions

What does 429 Too Many Requests mean?

The server limits how many requests a client may send in a period, and this client went over. Wait as long as the Retry-After header says, or back off if there is none, and send fewer requests.

How long should I wait after a 429?

At least as long as the Retry-After header says. Without it, wait a second or two and double the delay after each new 429, with some randomness, up to a limit.

Is 429 a client or a server error?

It is a 4xx client error: the server works, but the client sent too many requests. The fix is on the client side, by slowing down, unless the limit itself is set too low.

Why does my uptime monitor get 429 errors?

The checked server or its firewall rate limits the monitor’s address, often because several monitors hit the same host or the path has a strict limit. Exempt the monitor’s IP addresses, or check an endpoint without the limit.

Keep reading

Guides 5 min read

403 Forbidden Error: What It Means and How to Fix It

A 403 means the server understood the request and refused it. The usual causes, what visitors can try, how site owners find the rule that blocks, and why monitors see 403s browsers don’t.

Read

Guides 5 min read

API Monitoring Checklist: What to Check Beyond a 200 OK

An API can return 200 and still be broken. A practical checklist for API monitoring: methods, headers, request bodies, authentication, expected responses and response time thresholds.

Read

Guides 7 min read

How to Build a Health Check Endpoint (and Monitor It)

A health check endpoint tells monitors and load balancers whether your app can serve requests. What to check, how to keep it fast and safe, code for Laravel, Express and Flask, and how to monitor it.

Read

Downtime is obsolete.

Set up your first monitor in under a minute, or look around the live demo first.

14-day free trial · No credit card required