Rate limiting and throttling get used interchangeably in casual conversation, but they describe two different responses to the same problem: too many requests hitting an API in too short a window. Rate limiting draws a hard line and rejects requests that cross it. Throttling slows the pace of requests down to keep them under a target rate, without necessarily rejecting anything. The distinction matters because it changes what a client experiences and how you should design around it.
What changed in 2026
- Adaptive rate limiting became more common, where limits adjust dynamically based on backend load rather than a fixed number set in advance.
- Standardized rate-limit headers (
RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset) saw wider adoption following the IETF draft moving toward RFC status, replacing the inconsistent X-RateLimit-* conventions different APIs used before.
- Edge and CDN-layer rate limiting matured, pushing more enforcement out of application code and into infrastructure like API gateways and edge functions, reducing load on backend services.
- Cost-based limiting grew for AI and compute-heavy APIs, where limits are set by resource cost per request rather than a flat request count.
Rate limiting: hard rejection
Rate limiting enforces a quota, typically "N requests per time window," and rejects anything beyond it with an HTTP 429 Too Many Requests response. The client is expected to read the response, wait, and retry, often guided by a Retry-After header. This is simple to reason about and easy to communicate in API documentation, but it can feel abrupt to a client that just barely exceeded the limit.
Throttling: controlled pacing
Throttling instead slows the rate at which requests are processed, often by queueing or introducing delay, so the effective throughput stays under a target even if the client keeps sending requests. A throttled request usually still succeeds, just later. This is common inside systems that need to protect a downstream dependency, like a database or third-party API with its own limits, without rejecting the caller outright.
Comparing the two approaches
| Aspect |
Rate limiting |
Throttling |
| Client experience |
Request rejected (429) |
Request delayed or queued |
| Typical use |
Public API quota enforcement |
Protecting a downstream dependency |
| Client burden |
Must implement retry/backoff |
Often transparent to the client |
| Failure mode under load |
Fails fast |
Can build queue backlog |
Common rate limiting algorithms
- Fixed window counts requests in a fixed time block (e.g., per minute) and resets at the boundary. Simple, but allows a burst right at the boundary edge — up to double the intended rate across two adjacent windows.
- Sliding window smooths that edge case by weighting the current and previous window, giving a more accurate rolling count.
- Token bucket grants tokens at a steady rate up to a cap; each request consumes a token. This naturally allows short bursts (using saved-up tokens) while enforcing a long-run average — the most common choice for public APIs.
- Leaky bucket processes requests at a constant output rate regardless of burst, which behaves more like throttling than rejection-based limiting.
Designing limits that do not break legitimate clients
- Limit per API key or user, not globally, so one noisy client cannot exhaust the quota for everyone else.
- Return standard rate-limit headers on every response, not just when a client is throttled, so well-behaved clients can self-regulate before hitting the wall.
- Set tiered limits for different plan levels rather than one number for all traffic — this is where an API gateway typically enforces the policy centrally.
- Log and alert on clients repeatedly hitting limits — it often signals a retry loop bug on their end, not intentional abuse.
FAQ
Should I rate limit or throttle my public API?
Most public APIs use rate limiting with clear 429 responses, because clients need a predictable contract to build retry logic against. Throttling is more common internally, between your own services.
What HTTP status code should throttled requests return?
If a request is delayed rather than rejected, it typically still returns 200 once processed. If throttling ultimately results in rejection past some threshold, 429 is standard, same as rate limiting.
How do I choose a time window for rate limits?
Match it to the abuse pattern you are protecting against and the usage pattern of legitimate clients. Per-second windows suit real-time APIs; per-minute or per-hour windows suit typical CRUD or reporting APIs.
Does rate limiting protect against DDoS attacks?
Only partially. It helps against sustained abusive traffic from identifiable clients, but a distributed attack from many sources can still overwhelm infrastructure before per-client limits take effect. That is a job for edge-layer defenses in addition to application-level limits.
Where to go next