Frequency limit: token bucket or sliding window
Photo: Stytch

Frequency limit: token bucket or sliding window

Four common algorithms, each of which allows for a different type of explosion. Choosing the wrong one results in either a false positive or a false negative.

All public APIs require rate limiting. But "100 requests per minute" can be interpreted in at least four different ways, and each interpretation results in significantly different behavior.

Fixed window

Count the number of requests in each full minute; reset to 0 at the start of the next minute. This is the simplest approach, but it has a boundary condition vulnerability: a user could send 100 requests at the 59th second and another 100 requests at the 61st second—that is, 200 requests in two seconds—and it would still be valid.

Sliding window

Count the number of requests in the past 60 seconds, starting from the current time. There are no boundary issues, but storing the timestamp for each request consumes memory. A common compromise is to interpolate between the current window and the previous window.

Token wallet

A bag holds up to N tokens, which are replenished at regular intervals. Each request consumes one token; if there are no tokens left, the request is rejected.

The great thing is that it allows for controlled bursts: users can stay quiet for a while to fill up their queue, then send a rapid series of requests. With a real API, this is usually the desired behavior—people tend to send requests in batches rather than at regular intervals.

Leak

Requests are queued and processed at a fixed rate. This completely smooths out traffic and is suitable when the downstream system cannot handle spikes, but it introduces additional wait time.

How to Choose

  • API for Developers — Token Wallets, Because Short-Term Volatility Is Normal
  • Protecting what’s fragile behind the scenes — a leak bucket, to keep the incoming flow steady
  • Prevent abuse and spam — sliding window, because precise numbers are needed
No matter what you choose, it returns a header indicating how many attempts remain and when the counter resets. The lack of a clearly defined limit is the source of these pointless retry loops.
Chia sẻ

Thảo luận