Skip to content
YAS.SH
Developers

Rate Limiting: Token Bucket vs Sliding Window

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

mohamed-elsaadouni6 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.

The algorithms compared

Rate limiting is usually built on one of a few algorithms, each with a different shape of enforcement:

  • Fixed window — counts requests within a fixed time window (e.g. 60 per minute) and resets at the boundary. Simple and cheap, but vulnerable to a burst at the window boundary (traffic at the end of one window and the start of the next can double the effective rate).
  • Sliding window — counts requests over a continuously rolling window, so there is no boundary to exploit. More accurate, at the cost of a little more state or computation.
  • Token bucket — maintains a bucket that fills at a steady rate and drains per request; a request that finds no token is limited. It allows smooth bursts up to bucket capacity while capping sustained rate, which is why it is a common and forgiving choice for APIs.
  • Sliding log / fixed window counter variations — precise per-request logging or approximate counters that trade accuracy for scalability.

Choosing between them is about the trade between accuracy, cost, and how tolerant the workload is of bursts.

When each algorithm is the right fit

The choice depends on your shape of traffic and tolerance for bursts:

  • Token bucket is a strong default for APIs and link infrastructure: it lets a burst through up to the bucket size while capping the sustained rate, which feels fair to well-behaved clients without letting them hammer the endpoint.
  • Sliding window is preferable when you need a hard, precise cap with no boundary loophole — for example, login attempts where the security semantics require an exact per-window limit.
  • Fixed window is simplest and often good enough for coarse protection, provided you accept the boundary double-burst behavior.
  • Sliding log gives exact accounting for strict rate guarantees but can be memory-heavy at scale.

Matching the algorithm to the semantics of what you are protecting — smooth bursts vs strict caps vs exact accounting — is the practical decision.

The connection to client behavior

Whichever algorithm the server uses, the client contract is the same and is what makes it livable: read the rate-limit headers (RateLimit-Limit, Remaining, Reset, Retry-After), pace writes, and back off with Retry-After plus jitter on a 429. This is the behavior described in the rate limits explained guide. The server algorithm and the client discipline are two halves of the same system: the algorithm shapes what is allowed, and the client's cooperation is what keeps it painless for legitimate use.

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
Ask YAS AI
🍪 Cookies & privacy. Essential cookies keep you signed in and remember language and theme. Google AdSense and reCAPTCHA are Google technologies: AdSense runs only after Accept All; reCAPTCHA loads on sign-in and contact forms. See how Google uses data: https://policies.google.com/technologies/partner-sites cookie policy · privacy policy.
Settings