What only ThrottleKit does.
The incumbents are good at what they do — this isn't a teardown. It's the line between "counts requests" and "governs rate, concurrency, and cost behind a bound you can prove." Every ThrottleKit row is a shipped, tested feature; every benchmark — including the rows an incumbent wins — is reproducible on your hardware.
The simplest drop-in.
If you want a few lines of Express middleware to stop casual abuse, it's perfect — minimal, battle-tested, ubiquitous. It counts requests; that's the job.
The versatile workhorse.
Many backends, many algorithms, mature and widely deployed. On a single Redis or Postgres counter it's fast and solid — a strong general-purpose choice.
Serverless-native.
Built for edge/serverless on Upstash's REST Redis. If that's your stack, it fits the deployment model cleanly out of the box.
ThrottleKit is for the next tier of requirement: when "approximately right across the fleet" isn't good enough, when you need to govern LLM spend, or when you want one verified core behind every backend and language. The matrix below is what it adds on top.
| Capability | express-rate-limit | rate-limiter-flexible | @upstash/ratelimit | ThrottleKit |
|---|---|---|---|---|
| Provable, fleet-size-independent overshoot bound (TLA⁺-checked) | – | – | – | ✓ GALE |
| LLM token-budget escrow — the post-hoc cost axis | – | – | – | ✓ TALE |
| Unified rate × concurrency × cost in one decision | – | – | – | ✓ |
| Synchronous, allocation-free check | – | – | – | ✓ 169 ns |
| One algorithm, proven bit-identical across backends | – | – | – | ✓ 6 stores |
| Two-tier leasing — amortized round trips, bounded overshoot | – | – | – | ✓ |
| Weighted-fair share · overload shedding · fixed-memory DDoS sketch | – | – | – | ✓ |
| Polyglot from one verified core (Python today) | – | – | – | ✓ |
| Framework / transport adapters | 1 (Express) | a few | – | 13 |
| Zero runtime dependencies | – | – | – | ✓ |
This table is about distributed-correctness guarantees and breadth, and reflects each library's documented capabilities. All three incumbents do basic rate limiting well; the rows show what ThrottleKit layers on top, not a quality judgement of their core job.
- Redis: a dead heat. ThrottleKit and rate-limiter-flexible both do one atomic Lua round trip per request and land within noise (778 vs 752 ops/sec) — ThrottleKit has a slightly tighter tail, but there's no throughput story here.
- A single Postgres counter: rate-limiter-flexible wins. Its specialized one-statement
UPSERT(348 ops/sec) beats ThrottleKit's generic read-modify-write transaction (121 ops/sec) that reuses one proven transform across every strategy. AddtwoTier(leased)and that flips to a ~35× win — but on the raw shared counter, the upsert is faster. - Drop-in simplicity: express-rate-limit wins. If all you need is a few lines guarding an Express route, ThrottleKit is more than you need.
- Where ThrottleKit pulls ahead — the sync GCRA path computes a full decision in 169 ns (faster than express's bare counter bump at 199 ns), and the two-tier lever reaches 66.4k ops/sec where the incumbents have no equivalent. Full methodology →
- You run a fleet and "approximately the limit" isn't good enough — you need
admitted ≤ Limityou can point a model checker at. - You operate an LLM gateway and need to bound token spend, not just request count.
- You want rate, concurrency, and cost governed in one decision, not three bolted-together libraries.
- You need the same proven core behind Node and Python, across Redis / Postgres / DynamoDB / edge KV, byte-identically.
If none of those apply, the incumbent you already use is probably the right call — and ThrottleKit's benchmarks will tell you the truth either way.