Skip to content

Algorithm Comparison

Part of the Resilience documentation. See also: Algorithm deep-dives · Distributed rate limiting

Canonical identifiers used by the demo server and HTTP API: token_bucket, leaky_bucket, sliding_window (log and counter variants), fixed_window, gcra, adaptive.

Quick Comparison Table

Algorithm Burst Exact Memory Distributed Latency Added Use When
Token Bucket O(keys) None General API rate limiting
Leaky Bucket O(queue) ⚠️ Queue depth Constant output rate
Sliding Window Log O(req) None Exact counting
Sliding Window Counter ~99% O(keys) None High-volume approximate
Fixed Window O(keys) None Simplest, boundary burst ok
GCRA O(keys) None High-performance API

Performance

All in-memory limiters operate in the tens of nanoseconds per Allow call and allocate nothing on the hot path. Relative cost ordering (cheapest first):

  1. Fixed Window / Sliding Counter — a couple of counter updates.
  2. Token Bucket / GCRA — O(1) arithmetic per key, zero allocations.
  3. Sliding Window Log — grows with the number of timestamps in the window.
  4. Leaky Bucket — channel-backed queue per key.

Run the suite yourself to get numbers for your hardware and Go version:

make bench

Decision Guide

Need burst allowance?

Token Bucket or GCRA - Redis-optimal: GCRA - Well-understood: Token Bucket

Need strictly constant output rate?

Leaky Bucket (accepts queuing latency)

Need exact count, memory not a concern?

Sliding Window Log

Need approximate count, minimal memory?

Sliding Window Counter (1% error at boundary)

Simplest possible implementation?

Fixed Window (if boundary burst is acceptable)

Boundary Burst Explained

Fixed Window allows a burst of 2 × limit requests at a window boundary:

Window N:    [           100 requests           ]
Window N+1:  [100 requests           ...]
             200 requests in 1 second possible here

Sliding Window algorithms eliminate this: the effective window always spans exactly window duration ending at now.

Distributed Considerations

Every distributed variant executes a single atomic Lua script on one key, so it is safe under concurrency and compatible with Redis Cluster.

Algorithm Distributed variant Atomic? Notes
Token Bucket tokenbucket.NewDistributed Lua read-refill-consume in one round-trip
GCRA gcra.NewDistributed Single-timestamp update; most Redis-efficient
Fixed Window fixedwindow.NewDistributed INCR + PEXPIRE inside one script
Sliding Log slidingwindow.NewDistributedLog Sorted-set trim + count in one script
Sliding Counter slidingwindow.NewDistributedCounter Two-window weighted count
Leaky Bucket No distributed variant (ordered queue is hard to distribute)

See Distributed rate limiting for constructor signatures, fallback modes, and key naming.


See also: Algorithm deep-dives · Distributed rate limiting · README