GCRA (Generic Cell Rate Algorithm) is the default strategy in ThrottleKit. It tracks a single number per key — the theoretical arrival time (TAT), the earliest instant the next request would be perfectly paced — to produce a smooth, mathematically rigorous rate limit with a configurable burst allowance. Because the entire state is one float, GCRA costs O(1) memory and CPU, and its atomic Lua program is the smallest possible Redis script among all the strategies.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/AmeyaBorkar/throttlekit/llms.txt
Use this file to discover all available pages before exploring further.
Options
The sustained throughput: the maximum number of requests admitted per
periodMs. Together with periodMs, this derives the emission interval T = periodMs / limit (milliseconds between back-to-back requests at the steady rate).The period over which
limit applies, in milliseconds. For example, limit: 100, periodMs: 60_000 means 100 requests per minute.The maximum number of requests admissible instantaneously from a cold or idle key — the burst allowance. Defaults to
limit. A cold key (no prior traffic) admits exactly burst requests back-to-back, then paces at one request per T milliseconds. Request burst + 1 is denied. A single request whose cost exceeds burst can never be satisfied.How burst works
The burst allowance is implemented through the burst tolerance windowtau = T * burst. When a key has been idle long enough for the TAT to fall back to now, the first burst requests are all admitted instantly because now >= newTat - tau for each of them. After that, the algorithm enforces smooth pacing at the emission interval T.
Setting burst higher than limit lets a client absorb a short spike above the sustained rate. Setting burst: 1 means no instantaneous burst at all — every request must wait at least T milliseconds after the previous one.
burst defaults to limit, so a limiter configured with only limit and periodMs already allows the full limit as an instantaneous burst from a cold start. Set a lower burst if you want to cap spikes while preserving the same sustained throughput.Basic example
Deterministic testing with ManualClock
Isomorphic JS + Lua execution
GCRA’s decision logic is written once in TypeScript and compiled to an equivalent atomic Lua script. The Lua form stores the TAT asstring.format('%.17g', newTat) so it round-trips through Redis at full double precision. Both paths derive T, tau, and the admission test from the same integer inputs with identical rounding, so the in-process and Redis decisions are bit-identical — verified by a dual-path conformance suite.
GCRA vs token bucket
Both algorithms are mathematically equivalent in behavior, but differ in what they expose and store:| GCRA | Token Bucket | |
|---|---|---|
| State per key | One float (TAT) | Two floats (tokens, last) |
remaining | Derived from TAT math | Explicit token count |
| Wire footprint | Smaller (one Redis GET/SET) | Larger (Redis HASH) |
| Best for | Default choice, minimal overhead | Client-visible “tokens remaining” UX |
When to use GCRA
- General-purpose API rate limiting — the default choice for per-user, per-IP, or per-tenant limits.
- Smooth pacing — traffic emerges at a steady cadence rather than in bursts at window boundaries.
- High-throughput hot paths — at 169 ns/op and ~0 allocations on the synchronous in-process path, GCRA is the fastest strategy in ThrottleKit.
- Distributed systems — the one-float state minimizes serialization cost on remote stores.
Performance
| Path | Throughput | Latency |
|---|---|---|
checkSync (in-process) | 5.9M ops/s | 169 ns/op, ~0 B/op |
check (async, in-process) | 3.3M ops/s | ~300 ns/op |
Benchmarks measured on Node 24 / AMD Ryzen AI 9 HX 370, single hot key. See
BENCH.md for full methodology.