Why rate limits exist
A rate limit is a cap on how many requests you can send to an API in a given time window — say 100 requests per minute. APIs use them to prevent abuse, keep the service stable for everyone, and control costs. Hit the cap and the API responds with HTTP status 429 Too Many Requests.
How limits are usually expressed
Most APIs return headers telling you where you stand, such as X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (when the window resets). Reading these lets you slow down before you get blocked.
Handling 429 gracefully
- Respect Retry-After: if the response includes a
Retry-Afterheader, wait exactly that long before retrying. - Exponential backoff: if you must retry, wait progressively longer (1s, 2s, 4s...) with a little randomness to avoid stampedes.
- Cache responses so you don't re-request data you already have.
- Batch requests where the API supports it.
The mistake to avoid
Retrying a 429 immediately in a tight loop makes things worse — you burn your quota and can get temporarily banned. Always back off.
The common limiting algorithms
- Fixed window: count requests per calendar minute (or hour) and reset the counter at the boundary. Simple, but it lets a client send a burst at the end of one window and another at the start of the next.
- Sliding window: count requests over the last 60 seconds at any moment, which smooths out that boundary burst.
- Token bucket: tokens refill at a steady rate up to a maximum; each request spends one. This allows short bursts while enforcing an average rate, and is what many large APIs use.
- Concurrency limits: a cap on how many requests may be in flight at once, independent of the per-minute rate.
Reading the reset header correctly
APIs disagree on what X-RateLimit-Reset contains. Some send a Unix timestamp (seconds since 1 January 1970 UTC) for when the window resets; others send the number of seconds remaining. Read the documentation rather than guessing: treating a timestamp like 1760000000 as “seconds to wait” would pause your client for decades. Our Unix timestamp converter turns a value from a header into a readable date. The newer IETF draft standard uses RateLimit and RateLimit-Policy headers, and Retry-After can be either a number of seconds or an HTTP date.
Backoff in a few lines
A sensible retry loop waits min(cap, base × 2attempt) plus a random amount (“jitter”), gives up after a fixed number of attempts, and always prefers Retry-After when the server provides it. Jitter matters: without it, every client that was throttled at the same moment retries at the same moment, and the API is hit by a synchronised wave.
Designing a client that rarely sees 429
- Queue and pace: send work through a queue that releases requests at just under the documented rate.
- Use webhooks instead of polling when the API offers them.
- Request bigger pages when listing data — one request for 100 items beats ten for 10.
- Separate keys per environment so a test script cannot exhaust production's quota.
Limits are not only about you
A 429 is not always your fault. Shared limits per IP address can be triggered by other users behind the same corporate or mobile network, and some APIs lower limits during incidents. Log the rate-limit headers alongside errors so you can tell the difference later. For more on building well-behaved API clients, see our API and JSON best practices.
Frequently Asked Questions
What does HTTP 429 mean?
It means 'Too Many Requests' — you've exceeded the API's rate limit and should slow down before retrying.
What is exponential backoff?
A retry strategy where you wait progressively longer between attempts (1s, 2s, 4s...) to give the service time to recover.
How do I know my rate limit?
Check the API's documentation and the X-RateLimit-* response headers, which report your limit, remaining requests, and reset time.