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.
throttlekit/redis provides RedisStore — a distributed Store backed by Redis. Built-in
strategies run their atomic Lua form in a single EVALSHA round trip with an automatic EVAL
fallback on NOSCRIPT; custom strategies without a Lua form fall back to optimistic concurrency
(WATCH / MULTI / EXEC) with bounded retries. Three client adapters normalize the API surface
across ioredis, node-redis, and @upstash/redis.
RedisStore
RedisStore is an async-only store: it does not implement applySync, so limiter.checkSync will
throw. Use await limiter.check(key) on all Redis-backed limiters.
Options
An
ioredis (or compatible) client instance. Pass it through one of the factory adapters
(fromIoredis, fromNodeRedis, fromUpstash) to normalize the call shape. ioredis matches
RedisClientLike directly and can be passed without wrapping.Storage key namespace. Prepended to every Redis key as
prefix:key. Lets multiple independent
stores share one Redis instance without key collisions.Use the atomic Lua path for strategies that ship one. Default
true. Set false to force the OCC
fallback (useful when your Redis ACL forbids EVAL/EVALSHA).Derive
now from the Redis server clock (TIME) inside the script, so node clock skew cannot
corrupt shared state. Default true. Set false for deterministic tests that pass an explicit
now via a ManualClock.Bounded retries for the optimistic-concurrency fallback (custom strategies). Default
5. Exceeding
this limit throws a StoreUnavailableError.Floor in ms on the physical Redis key TTL, decoupling GC from the strategy’s logical window.
Default
0. Set this when using useServerTime: false to prevent a logically-live key from being
reclaimed by real-time PEXPIRE before the logical window ends.Client Adapters
Three factories translate each client’s native API intoRedisClientLike, the single shape
RedisStore speaks internally.
fromIoredis(client)
Identity adapter for ioredis. ioredis already satisfies RedisClientLike, so this is a no-op
shim provided for uniform code style.
fromNodeRedis(client)
Adapt the official redis (node-redis) client. Both the Lua and OCC paths work. Each OCC
transaction gets its own dedicated connection via client.duplicate() so concurrent checkMany
calls cannot cross-contaminate each other’s WATCH state.
fromUpstash(client)
Adapt an @upstash/redis REST client for serverless and edge runtimes (Vercel, Cloudflare,
Deno, Bun). Built-in strategies (all Lua-backed) work fully. Custom strategies that require
optimistic concurrency (WATCH / MULTI) throw a StoreUnavailableError — the Upstash REST
API does not support interactive WATCH.
Client Types
RedisClientLike
The minimal interface RedisStore needs. ioredis satisfies this structurally.
RedisMultiLike
The subset of a Redis transaction (MULTI) used by the optimistic-concurrency fallback.
NodeRedisMultiLike
The subset of a node-redis MULTI chain ThrottleKit uses.
NodeRedisLike
The slice of redis (node-redis) ThrottleKit uses. A RedisClientType satisfies it.
UpstashRedisLike
The slice of @upstash/redis ThrottleKit uses. Redis from @upstash/redis satisfies it.
Cluster Hash-Tag Behavior
On a Redis Cluster,EVAL / EVALSHA require that all KEYS used in the script hash to the same
slot. ThrottleKit strategies that use multiple keys (e.g. sliding window log’s sorted set) implement
LuaProgram.buildKeys(key) to apply a consistent hash tag to the keys they touch, so all of a
key’s state lands in the same slot automatically.
For prefix-based namespacing on Cluster, include a hash tag in your prefix:
EVALSHA Script Caching
RedisStore caches SHA-1 digests of each Lua script in-process and attempts EVALSHA first. On a
NOSCRIPT error (script cache flushed after a restart or failover) it falls back to EVAL, which
re-caches the script on the Redis server for subsequent calls. This is transparent — all strategies
remain fully functional across restarts with no manual script loading step.