Skip to content
Y
YAS.SH
Developers

Rate Limiting: Token Bucket vs Sliding Window

The algorithms behind per-IP and per-user throttles.

mohamed-elsaadouni9 min readrate-limitsapisecurity
Rate Limiting: Token Bucket vs Sliding Window
Featured imageRate Limiting: Token Bucket vs Sliding Window

Rate Limiting: Token Bucket vs Sliding Window

Rate limiting is what keeps a public API alive: it stops one caller from hogging resources, blocks brute force and scraping, and keeps the service fair. But "rate limit" isn't a single technique — the algorithm you choose determines how bursts are handled, how strict the limit feels, and how much memory it uses.

This guide compares the three most common approaches — token bucket, fixed window, and sliding window — and helps you choose.

Why the algorithm matters

A naive "X requests per minute" has a hidden problem: bursts at window boundaries. If you count in fixed one-minute windows, a client can fire a burst at the end of one window and again at the start of the next, doubling their rate without technically exceeding your limit. The algorithm is how you control that.

Token bucket

How it works: think of a bucket that holds a number of "tokens." Each request consumes a token. Tokens refill at a steady rate. If the bucket is empty, requests are rejected until it refills.

  • Allows bursts — if the bucket was full, a burst of requests can pass.
  • Steady refill — over time, the rate is smooth.
  • Memory-light — only need to track tokens + last refill time per key.

Best for: most APIs where you want to allow occasional bursts (e.g. a spike during a campaign) while capping sustained usage. This is a very common default.

Trade-off: bursts are allowed up to bucket capacity, so if you need a hard, even ceiling, it's less strict.

Fixed window

How it works: divide time into fixed windows (e.g. per minute). Count requests in the current window; reject when the count hits the limit; reset at the window boundary.

  • Simple — easy to implement.
  • Memory-light — one counter per key per window.

Trade-off: the boundary problem — a client can burst at the end of one window and the start of the next, effectively doubling throughput. Simple to code, but weak against burst abuse.

Sliding window

How it works: instead of fixed windows, use a rolling time window — e.g. "requests in the last 60 seconds." You track timestamps (or use weighted counts of overlapping windows) and reject once the count in the rolling window exceeds the limit.

  • Strict, even limit — no boundary double-spend.
  • Fair — a client can't exploit window edges.

Trade-off: more memory (tracking timestamps) and slightly more complexity than a fixed window.

Comparing them

Algorithm Bursts Strictness Memory Complexity Best for
Token bucket Allows (bounded) Medium Low Low Most APIs, burst-friendly
Fixed window Allows boundary spikes Low Low Very low Simple prototypes, non-critical
Sliding window Minimal High Higher Medium Strict, even limits; sensitive endpoints

Choosing for your use case

  • General API accesstoken bucket. It allows reasonable bursts (a user clicking quickly) while capping sustained use. Light on memory.
  • Login / brute-force protectionstricter limits. Per-account and per-IP limits with lockout; a sliding window or a small fixed window with escalating backoff works well. You want to block bursts, not allow them.
  • Resource-heavy endpointsstrict limits (sliding window) so a burst can't hammer an expensive operation.

A real service often layers these: token bucket for general usage, plus tighter per-IP and per-account limits on sensitive actions like login, signup, and link creation.

How this applies to a URL shortener

Shorteners are a target for abuse: automated link creation, brute-forcing custom codes, scraping, and spam. A good shortener rate-limits:

  • Per IP — cap requests to stop a single source hammering you.
  • Per user/account — cap operations (e.g. link creation per minute) so a compromised or malicious account can't flood.
  • On sensitive endpoints — stricter limits on login/register than on read-only lookups.

By choosing token bucket for general use and strict per-IP/per-user limits for sensitive actions, you keep real users happy while stopping abuse.

The takeaway

Rate limiting isn't one thing — the algorithm decides how bursts behave. Token bucket for burst-friendly general access, sliding window when you need a strict, even limit, and fixed window only where simplicity beats strictness. Layer per-IP and per-user limits on top, and you protect the service without frustrating real users.

See how idempotency keys pair with rate limiting to make retries safe, and how API keys scope automated access.

Frequently asked questions

What's the difference between token bucket and sliding window rate limiting?

A token bucket allows controlled bursts (it accumulates capacity over time). A sliding window gives a strict, even limit by looking at a rolling time window. Fixed window is simpler but can allow spikes at boundaries.

Which rate limiting algorithm is best?

There's no single best — it depends on your goal. Token bucket is great for allowing bursts; sliding window is great for strict, even limits. Many APIs use token bucket because it's burst-friendly and easy to implement.

Why do rate limiters matter for a URL shortener?

Shorteners are a prime abuse target. Rate limiting per IP and per user prevents automated link creation, brute force, and scraping while keeping the service available to real users.

Was this helpful? Share
🍪 Cookies & privacy. yas.sh uses only essential cookies to keep you signed in and remember your preferences. We do not run third-party trackers. See our cookie policy and privacy policy.
Settings