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
220 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
67 /100 Good
Development Activity 80
Maintenance 56
Community 52
Maturity 60
Momentum 20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
75 /100 Good
Architecture 85
Code Quality 88
Innovation 72
Learning Curve 55

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

AI Development · Automation · Developer Tools

55,490

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

View details
82
Repo Health
77
Technical
63
Dependency
Built with
TypeScript 62%
JavaScript 27%
Updated 1 months ago
TypeScript
91%
Apache 2.0

Helicone

AI Development · Analytics · Monitoring

6,182

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
70
Repo Health
81
Technical
65
Dependency
Built with
TypeScript 91%
Updated 3 weeks ago
JavaScript
46%
MIT

Kutt

Analytics · Marketing

11,125

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

View details
74
Repo Health
62
Technical
72
Dependency
Built with
JavaScript 46%
Handlebars 24%
HTML 16%
Updated 1 months ago
TypeScript
82%
MIT

LibreChat

AI Assistants · Developer Tools

45,009

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
TypeScript 82%
JavaScript 17%
Updated 1 weeks ago
JavaScript
26%
AGPL 3.0

Omnivore

Bookmarks Archiving · Knowledge Management · Note Taking

16,265

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

View details
90
Repo Health
74
Technical
65
Dependency
Built with
JavaScript 26%
TypeScript 25%
HTML 19%
Updated 1 weeks ago
JavaScript
98%
Apache 2.0

Parse Server

Databases · Developer Tools

21,405

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
77
Dependency
Built with
JavaScript 98%
Updated 1 weeks ago

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