rate-limit-redis

A Redis-backed store for express-rate-limit that shares rate limit counters across multiple Node.js server instances.

Library
npm
v6.0.1
219stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
66/100Good
Development Activity76
Maintenance56
Community52
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
75/100Good
Architecture85
Code Quality88
Innovation72
Learning Curve55

rate-limit-redis implements the Store interface required by the express-rate-limit middleware, backing it with Redis (or Redis-protocol-compatible servers like Redict and Valkey) instead of in-memory storage. This lets rate limit counts stay consistent across horizontally scaled apps, multiple processes, and load-balanced servers, where each instance would otherwise track its own separate count.

Rather than depending on a specific Redis client, the library takes a sendCommand (or sendCommandCluster for cluster-aware routing) callback supplied by the consumer, so it works with node-redis, ioredis, or any client capable of sending raw commands. Internally it loads two small Lua scripts onto the Redis server and executes them atomically via EVALSHA, avoiding the race conditions a naive GET-then-SET/INCR sequence would introduce under concurrent requests, with automatic script-reload retries if Redis reports NOSCRIPT.

What You Get

  • A RedisStore class implementing express-rate-limit’s Store interface, ready to pass to the store option of rateLimit()
  • Atomic increment-and-check semantics via server-side Lua scripts (EVALSHA), avoiding race conditions between concurrent requests for the same key
  • Client-agnostic design via a sendCommand/sendCommandCluster callback, with documented adapters for node-redis, ioredis, handy-redis, tedis, redis-fast-driver, yoredis, and noderis
  • Built-in Redis Cluster support through sendCommandCluster, which carries key and read/write routing details to the correct cluster node
  • Automatic reload-and-retry when a NOSCRIPT error indicates the cached Lua script was evicted from Redis
  • Dual ESM/CJS builds with full TypeScript type definitions, including exported types for the command-sending callbacks

Common Use Cases

  • Rate limiting Express APIs that run as multiple processes or containers behind a load balancer, where in-memory counters would diverge per instance
  • Sharing rate limit state across a PM2 cluster-mode or Kubernetes deployment of the same Node.js service
  • Adding request throttling to an app that already runs Redis, Redict, or Valkey for caching, without introducing a second piece of infrastructure
  • Rate limiting in front of a Redis Cluster, using sendCommandCluster to route increment/get commands to the correct shard

Under The Hood

Architecture The package is a thin, single-responsibility module: source/types.ts defines the Options/SendCommandFn contracts, source/scripts.ts holds two whitespace-normalized Lua scripts (increment, get), source/lib.ts implements the RedisStore class against express-rate-limit’s Store interface, and source/index.ts re-exports everything as the public API. The constructor validates that exactly one of sendCommand/sendCommandCluster is supplied (throwing otherwise) and normalizes both into a single internal sendCommand shape; init() eagerly loads both Lua scripts via SCRIPT LOAD and stores their SHA1s as promises so calls made before loading completes simply await the same promise. increment/get execute EVALSHA against those scripts, with a isNoScriptError type-guard and reload-and-replay path if Redis reports the script was evicted. Because every operation funnels through the single injected command function, that callback is the one abstraction the whole class depends on — swapping or breaking it affects every method uniformly.

Tech Stack Written in TypeScript 5.2 against a shared @express-rate-limit/tsconfig, built with pkgroll (esbuild-based) into dual ESM (.mjs)/CJS (.cjs) bundles with matching .d.mts/.d.cts type declarations, per the package’s exports map. express-rate-limit (>=8.6.0) is a peer dependency, not bundled. There are no runtime dependencies at all — the library intentionally avoids depending on any specific Redis client, instead accepting a caller-supplied command function. The dev/test stack uses Jest 29 with ts-jest and ioredis-mock for Redis-free tests, xo (an ESLint preset) plus a shared Prettier config for linting/formatting, and husky/lint-staged for pre-commit enforcement, with CI defined in .github/workflows/ci.yaml.

Code Quality A single test file (test/store-test.ts, 457 lines, 28 cases) exercises get/increment/decrement/resetKey/init, both cluster and non-cluster configuration, key prefixing, and the NOSCRIPT retry path against ioredis-mock, which is proportionate coverage for the module’s small surface. Error handling is explicit and typed: the constructor throws TypeError/Error for missing, dual, or removed configuration options, and parseScriptResponse throws on malformed Redis replies rather than failing silently; isNoScriptError uses a type predicate to safely narrow a caught unknown before pattern-matching its message. Naming is consistent and descriptive throughout (retryableIncrement, prefixKey, loadIncrementScript), and the codebase shows no use of any in the reviewed source files. Linting (xo) and formatting are enforced both locally via lint-staged/husky and in CI.

API Design The public surface is essentially one class, RedisStore, that satisfies express-rate-limit’s Store interface, so wiring it in is typically a two-line change regardless of which Redis client the consumer already runs. Rather than depending on and re-exporting a specific client, the library asks for a thin sendCommand/sendCommandCluster raw-command function, and the README documents exact one-line adapters for six different Redis client libraries plus a dedicated cluster-routing path carrying key/isReadOnly/command metadata. Exported types (RedisReply, SendCommandClusterDetails) give consumers full inference when writing their adapter. The pattern itself is a standard store-adapter shape rather than a novel one, but it is executed with unusually broad client compatibility and clean cluster support for a package this size.

Used by 6 apps in this directory

TypeScript
62%
Other

Flowise

Developer Tools · Automation · No Code Platforms

55,427

Drag-and-drop visual builder for AI agents, RAG pipelines, and multi-agent systems—deploy anywhere in minutes.

View details
86
Repo Health
77
Technical
63
Dependency
Built with
TypeScript62%
JavaScript27%
Updated 3 weeks ago
TypeScript
91%
Apache 2.0

Helicone

Monitoring · AI Development · Analytics

6,133

An open-source AI gateway and LLM observability platform that routes requests to 100+ models while logging cost, latency, and full traces for every call.

View details
69
Repo Health
81
Technical
65
Dependency
Built with
TypeScript91%
Updated 1 weeks ago
JavaScript
46%
MIT

Kutt

Analytics · Marketing

11,080

Self-hosted URL shortener with custom domains, per-link analytics, and zero build step required.

View details
78
Repo Health
62
Technical
72
Dependency
Built with
JavaScript46%
Handlebars24%
HTML16%
Updated 4 days ago
TypeScript
81%
MIT

LibreChat

Developer Tools · AI Assistants

42,871

Unite every major AI model in one self-hosted chat platform with agents, code execution, MCP tools, and enterprise authentication.

View details
93
Repo Health
81
Technical
65
Dependency
Built with
TypeScript81%
JavaScript18%
Updated today
JavaScript
26%
AGPL 3.0

Omnivore

Knowledge Management · Bookmarks Archiving · Note Taking

16,228

Self-hosted read-it-later platform with highlights, newsletters, PDFs, and seamless Obsidian and Logseq integration.

View details
88
Repo Health
74
Technical
65
Dependency
Built with
JavaScript26%
TypeScript25%
HTML19%
Updated 2 days ago
JavaScript
98%
Apache 2.0

Parse Server

Developer Tools · Databases

21,414

Self-hosted Backend-as-a-Service for Node.js with REST, GraphQL, real-time Live Query, cloud code, and pluggable adapters for any infrastructure.

View details
98
Repo Health
81
Technical
78
Dependency
Built with
JavaScript98%
Updated yesterday

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search