HomeNetworks & Graph TheoryAPI Rate Limiter: Token Bucket, Fixed & Sliding Window

🚦 API Rate Limiter: Token Bucket, Fixed & Sliding Window

Watch requests hit a live API gateway and see token bucket, fixed window, and sliding window rate limiting decide what gets through. Tune burst capacity, sustained rate and window length and trigger a burst to see the boundary-burst problem.

Networks & Graph Theory3DModerate60 FPS
api-rate-limiting-token-bucket-sliding-window-simulation ↗ Open standalone

About this simulation

This simulator runs a live request stream through three real rate-limiting algorithms — token bucket, fixed window and sliding window — against the exact same traffic, so the difference in behaviour is visible rather than theoretical. Tune the client's send rate, the sustained limit, and the burst capacity or window length, then hit Send burst to see how each algorithm handles a sudden spike: the token bucket absorbs it up to its capacity, the fixed window can let through nearly double the limit right at a window boundary, and the sliding window smooths that boundary burst by blending the previous and current window counts.

🔬 What it shows

Requests travel from client to server as particles; at the gate each one is tested against the active algorithm and turns green (admitted) or red (rejected, HTTP 429). The gate itself visualises the algorithm's internal state: a filling token bucket, a sweeping window ring, or a pair of weighted window bars.

🎮 How to use

Pick an algorithm, set the client send rate, sustained limit and burst capacity / window length, then click Send burst to inject 24 requests at once and watch how each algorithm's admit/reject pattern differs on the live chart.

💡 Did you know?

A fixed window with a 100-request limit can theoretically admit close to 200 requests in the two seconds spanning a window boundary — 100 at the very end of one window and 100 at the very start of the next — which is exactly why many production gateways default to token bucket instead.

Frequently asked questions

Why is fixed window rate limiting still used if it has a known burst flaw?

It is the cheapest to implement and reason about, requiring only a single integer counter and a reset timestamp per client, with negligible storage overhead even at massive scale. For rate limits that exist mainly as a coarse abuse-prevention backstop rather than a precise SLA guarantee, the boundary burst weakness is often an acceptable trade-off against its simplicity and low cost.

Is token bucket the same thing as leaky bucket?

No, they are near-opposites in effect despite sharing the word 'bucket.' Token bucket allows bursts up to a capacity and rejects or delays only the excess, prioritizing throughput and burst tolerance. Leaky bucket forces a constant output rate regardless of input burstiness by queueing excess requests, prioritizing smoothness and predictability for the downstream system at the cost of added latency.

How do distributed API gateways enforce a single rate limit across many servers?

Most use a shared, low-latency data store — commonly Redis — to hold each client's token count or request timestamps, with atomic increment-and-check operations (e.g., Lua scripts in Redis) to avoid race conditions where two servers both check the counter before either updates it. Some systems trade perfect global accuracy for lower latency by using local approximate counters that periodically synchronize, accepting slightly looser enforcement in exchange for not adding a network round-trip to every request.

What does the HTTP 429 status code and Retry-After header actually communicate?

HTTP 429 (Too Many Requests) tells the client its request was rejected specifically due to rate limiting rather than a server error or bad input. The accompanying Retry-After header (in seconds, or as a timestamp) tells a well-behaved client how long to wait before retrying, which lets clients implement backoff correctly instead of guessing or retrying immediately and making the overload worse.

Why does the sliding window need only two counters instead of a full timestamp log?

By assuming request arrivals are roughly uniform within a window, it can approximate the true rolling count from just the previous window's total and the current window's running total, weighted by how far into the current window the clock has moved. This trades a small amount of accuracy for far less memory than a sliding window log, which must store one timestamp per request.

⚙ Under the hood

Watch the same request stream hit a token bucket, a fixed window and a sliding window rate limiter, trigger a burst, and see which algorithm lets through nearly double its limit at a window boundary.

Three.jsInstancedMeshOrbitControlsNetworkingQueueing TheoryDistributed Systems

3D · Three.js / WebGL renderer · 60 FPS target · runs fully client-side, no install

What did you find?

Add reproduction steps (optional)