Redis Store (@universal-rate-limit/redis)
Redis store using Lua scripts for atomic operations. Works with any Redis client.

Redis store for universal-rate-limit. Uses atomic Lua scripts to prevent race conditions — works with any Redis client library.
universal-rate-limit is a web-standards-based rate limiter with fixed-window, sliding-window, and token-bucket algorithms, IETF-compliant headers, and drop-in middleware for Express, Fastify, Hono, and Next.js. This package lets you back it with Redis for multi-instance
deployments.
Try the playground to see rate limiting in action.
Install
npm install @universal-rate-limit/redis universal-rate-limitUsage
Provide a sendCommand function that sends raw Redis commands. This makes the store compatible with any Redis client (redis, ioredis, Upstash, etc.).
With node-redis
import { createClient } from 'redis';
import { rateLimit } from 'universal-rate-limit';
import { RedisStore } from '@universal-rate-limit/redis';
const client = createClient();
await client.connect();
const limiter = rateLimit({
algorithm: { type: 'sliding-window', windowMs: 60_000 },
limit: 60,
store: new RedisStore({
sendCommand: (...args) => client.sendCommand(args)
})
});With ioredis
import Redis from 'ioredis';
import { rateLimit } from 'universal-rate-limit';
import { RedisStore } from '@universal-rate-limit/redis';
const redis = new Redis();
const limiter = rateLimit({
algorithm: { type: 'sliding-window', windowMs: 60_000 },
limit: 60,
store: new RedisStore({
sendCommand: (...args) => redis.call(args[0], ...args.slice(1))
})
});Options
new RedisStore({
sendCommand, // Required — function that sends raw Redis commands
prefix: 'rl:' // Key prefix for all rate limit keys
});Token-bucket time authority
Token-bucket consume and peek operations use Redis server time inside their atomic Lua scripts. Refill timestamps never move backward, so application clock skew and request reordering do not subtract tokens or grant refill. Retry and reset values remain relative durations when they cross the Redis boundary, and bucket expiry retains state through a backward Redis-clock interval plus the refill horizon.
Documentation
License
MIT