Rate limit
A cap on how fast a client may call an API, usually expressed as requests per second or per minute. It protects the service from one client consuming capacity meant for everyone.
A rate limit governs speed. A quota governs volume. They solve different problems and a serious API needs both: a quota stops a customer using more than they paid for over a month, and a rate limit stops any single client from saturating your infrastructure in the next ten seconds.
Two implementations cover most cases. A fixed window counts requests per clock minute and is trivial to build, but it allows a burst of double the limit across a window boundary. A token bucket refills at a steady rate up to a maximum, which permits a controlled burst and then settles to the sustained rate. The token bucket is usually the better fit, because real clients are bursty and rejecting a short spike from an otherwise well-behaved integration is a poor experience.
What matters as much as the algorithm is telling the client what is happening. Return HTTP 429 when the limit is exceeded, and include headers on responses so a client can pace itself:
X-RateLimit-Limit, the ceiling for the windowX-RateLimit-Remaining, what is leftX-RateLimit-Reset, when it refillsRetry-Afteron the 429 itself
Retry-After is the important one. Without it every client guesses, and guesses cluster, which is how a retry storm starts. With it, a client using exponential backoff can wait exactly the right amount of time.
A worked example. A plan allows 10 requests per second with a bucket size of 30. A customer’s nightly job fires 30 requests at once, all of which succeed by draining the bucket, then settles into a steady 10 per second as the bucket refills. If it pushes to 50 per second, the excess receives 429 with Retry-After: 1, and a correctly written client slows down rather than failing the job.