429 Too Many Requests: what it means and how to fix it

429 Too Many Requests means the server is rate limiting you: you've sent more requests in a given window than it allows, so it refused this one without processing it. It isn't a failure of the server. It's a request to slow down, and the response often says exactly how long to wait in a Retry-After header.

HTTP/1.1 429 Too Many Requests
Retry-After: 30
Content-Type: application/json

{"error": "rate_limited", "message": "Too many requests, retry in 30 seconds"}

Common causes

  • An API's rate limit. GitHub, Stripe, OpenAI, Shopify and most public APIs cap requests per second, minute or hour, per key or per IP.
  • Your own gateway or proxy. Cloudflare rate-limiting rules, AWS API Gateway throttling, nginx limit_req and Kong all answer 429 when a client goes over a limit.
  • Retry storms. A client that retries immediately on failure multiplies its own traffic and stays over the limit.
  • Webhook bursts. A provider replays a backlog or a batch job fires thousands of events at once, and your endpoint (or the API it calls) rate-limits them.

How to fix a 429 as a client

  1. Honour Retry-After. It's either seconds (Retry-After: 30) or an HTTP date. Don't send the request again before then.
  2. Back off exponentially with jitter when there's no header: wait 1s, 2s, 4s, 8s… plus a random offset so many clients don't retry in lockstep. See exponential backoff.
  3. Read the rate-limit headers. Many APIs send X-RateLimit-Remaining and X-RateLimit-Reset (or the standard RateLimit / RateLimit-Policy headers) so you can slow down before you hit 429.
  4. Batch and cache. Fewer, larger requests and cached responses use less of your quota.
  5. Ask for a higher limit if your steady-state traffic is legitimately above it.

429s on a webhook endpoint

When your webhook receiver answers 429, most providers count it as a failed delivery and retry. That's good for durability, but the retries land on an endpoint that's already over its limit. Raising the limit only moves the problem downstream to your database or the API your handler calls.

The usual fix is to put a buffer between the sender and your endpoint and release events at a pace the endpoint can handle. With Webhook Relay outbound throttling, you set a rate (for example 10 requests per second) or a maximum concurrency per destination. A burst of 5,000 events turns into a steady stream, nothing is dropped, and events are delivered oldest first. If the destination still fails, durable retries keep trying with backoff for up to 30 days.

When to return 429 from your own API

Return 429 (not 503 or 400) when a specific client is over its quota, and include Retry-After. Use 503 Service Unavailable when the whole service is overloaded or down for everyone.

Frequently asked questions

What does 429 Too Many Requests mean?

HTTP 429 means the server is rate limiting you: you sent more requests in a time window than it allows. The request wasn't processed. Wait and retry, ideally after the delay the server gives in its Retry-After header.

How long should I wait after a 429?

If the response has a Retry-After header, wait that long: it is either a number of seconds or an HTTP date. If there's no header, retry with exponential backoff and jitter, for example 1s, 2s, 4s, 8s plus a random offset, and cap the number of attempts.

Is 429 a client error or a server error?

It's a 4xx client error: the server is working, but it refuses this request because the client is over its limit. Unlike most 4xx errors, a 429 is meant to be retried later.

Why does my webhook endpoint return 429?

Usually a burst. A provider replays a backlog, a sale or batch job fires thousands of events, or your own rate limiter or API gateway (Cloudflare, AWS API Gateway, nginx limit_req) caps requests per second. Most providers treat 429 as a failed delivery and retry, so the burst comes back again. Throttle delivery to a pace the endpoint can handle instead of raising the limit.