All posts
Monitoring3 min readWatchFor Team

Rate Limiting & HTTP 429 Explained

Rate limiting is how services protect themselves from too many requests — and HTTP 429 is how they say 'slow down'. Here's how it works, and how to handle it gracefully on both sides.

Rate Limiting & HTTP 429 Explained

A single misbehaving script — a runaway integration, an over-eager scraper, a retry loop gone wild — can send thousands of requests a second and bring a service to its knees. Rate limiting is the bouncer that stops that from happening, and HTTP 429 is the polite-but-firm "you've had enough, slow down."

If you build or consume APIs, you'll meet both. Here's how they work — from both sides of the door.

What rate limiting is

Rate limiting caps how many requests a client can make in a given window of time — say, 100 requests per minute. Go over, and further requests are rejected (usually with a 429) until the window resets.

It exists to protect a service from being overwhelmed, whether the cause is malicious or just a bug.

Why services do it

ReasonWhat it prevents
StabilityOne heavy client starving everyone else
AbuseScrapers, brute-force attacks, spam
Cost controlRunaway usage running up infrastructure bills
FairnessSharing capacity evenly across all users

Rate limiting is a feature, not hostility. A service that limits you is protecting its reliability — and therefore your experience of it — from whoever's hammering it hardest.

How it works (the token bucket)

The most common mechanism is a token bucket: you get a bucket of tokens that refills at a steady rate. Each request spends a token. Requests are allowed while there are tokens; when the bucket's empty, you're limited until it refills. It's simple and it smoothly allows short bursts while capping the sustained rate.

Limits are usually applied per client — per API key, per user, or per IP — so one noisy neighbour doesn't affect everyone.

Meet HTTP 429

When you exceed a limit, a well-behaved API returns 429 Too Many Requests. Crucially, it often includes headers telling you how to behave:

  • Retry-After — how long to wait before trying again.
  • X-RateLimit-Remaining / X-RateLimit-Reset — how many requests you have left and when the window resets.

These headers are gold: they let a good client back off exactly as much as needed, instead of guessing.

Handling 429 as a client

If you're calling an API and hitting 429s, don't just retry immediately — that makes it worse. Instead:

  1. Respect Retry-After. If the server told you when to come back, do that.
  2. Use exponential backoff with jitter. Wait, then wait longer each retry, with a little randomness so all your clients don't retry in sync.
  3. Watch the rate-limit headers. Slow down before you hit the wall, using the "remaining" count.
  4. Cache and batch. The best way to avoid limits is to make fewer requests in the first place.

Implementing it as a service

If you're the one applying limits:

DoWhy
Limit per API key / user, not globallyOne client's surge shouldn't hit everyone
Return 429 with Retry-AfterTell clients exactly how to behave
Expose remaining/reset headersLets good clients self-regulate
Set sane, documented limitsSurprises break integrations
Consider burst allowanceToken buckets handle short spikes gracefully

The bottom line

In one line
WhatA cap on requests per time window.
WhyStability, abuse prevention, cost, fairness.
429"Too many requests" — back off, respect Retry-After.
As a clientBackoff with jitter; watch the headers; make fewer calls.

Rate limiting keeps shared services healthy, and 429 is just the system asking you to play nice. Handle it gracefully — back off, respect the headers, and reduce your call volume — and you'll have far more reliable integrations.

If you build APIs, monitor them (and their limits) with the API monitoring guide, and brush up on HTTP status codes.

Share this article