@nest-lab/throttler-storage-redis
A Redis-backed storage provider for @nestjs/throttler, letting rate-limit counters survive restarts and be shared across horizontally-scaled NestJS instances.
Repository Health
Technical Analysis
@nest-lab/throttler-storage-redis plugs into @nestjs/throttler as a drop-in replacement for its default in-memory storage, moving rate-limit hit counts and block state into Redis. Because the counters live outside the process, every replica of a horizontally-scaled NestJS deployment enforces the same limits instead of each instance tracking its own independent count.
The implementation centers on a single Lua script executed atomically via EVAL, which increments a hit counter, checks it against the configured limit, and sets a block key when the limit is exceeded — all in one round trip to avoid race conditions between concurrent requests. The service accepts a raw connection URL, an existing ioredis Redis or Cluster instance, or RedisOptions, so it fits into whatever Redis setup an application already has, including Redis Cluster topologies.
It originated as an independent package (nestjs-throttler-storage-redis) before being folded into the jmcdo29/nest-lab monorepo, which also hosts a handful of other small NestJS integration packages (a Fastify multer adapter, an OR-guard helper, and a typeschema validator). The throttler-storage-redis package is published and versioned independently via changesets, with its own test suite that exercises both single-instance and cluster Redis, and both the Express and Fastify HTTP adapters.
What You Get
- A
ThrottlerStorageRedisServiceclass implementing@nestjs/throttler’sThrottlerStorageinterface, ready to pass intoThrottlerModule.forRoot/forRootAsync - Flexible construction: pass nothing (defaults to localhost:6379), a connection URL string, an existing
ioredisRedis/Clusterinstance, or aRedisOptionsobject - Atomic increment-and-check logic via a single Lua script (
EVAL), avoiding race conditions between concurrent requests hitting the same key - Native support for Redis Cluster deployments, using hash-tagged keys (
{key}:hits) so related keys land on the same cluster slot - Automatic connection cleanup via NestJS’s
OnModuleDestroylifecycle hook when the service created its own Redis connection
Common Use Cases
- Enforcing consistent API rate limits across multiple replicas of a NestJS service running behind a load balancer
- Preserving rate-limit state across application restarts or deployments, instead of resetting all counters to zero
- Sharing throttling state between separate NestJS microservices that need to respect a common limit for the same client/API key
- Building tiered or per-route rate limiting where limit and block-duration values differ, backed by a durable, centralized store
Under The Hood
Architecture
The package is a single injectable NestJS service, ThrottlerStorageRedisService, implementing a small ThrottlerStorageRedis interface plus NestJS’s OnModuleDestroy. The constructor is heavily overloaded to accept a Redis instance, a Cluster instance, connection options, or a URL string, normalizing all of them to an internal redis client while tracking whether the service itself opened the connection (so it knows whether to disconnect on module teardown). The core logic lives in one increment() method that runs a Lua script via redis.call('eval', ...), keeping the hit-count, TTL, and block-state checks atomic in a single round trip rather than issuing multiple separate Redis commands that could race under concurrent load. There is no other internal layering — the whole surface area is this one service plus a type-only interface file, which keeps the abstraction easy to reason about and hard to misuse.
Tech Stack
Written in TypeScript on top of @nestjs/common/@nestjs/core (peer dependencies spanning NestJS 7 through 11) and ioredis (peer dependency >=5.0.0) as the Redis client, with reflect-metadata and @nestjs/throttler as additional peers. The package lives inside an Nx-managed pnpm monorepo (nest-lab), built via @nx/js:tsc into a standalone publishable package, and versioned/released independently through @changesets/cli. Local development tests run against real Redis via docker-compose.yml, wired into Nx targets (start-docker → wait-for-docker → run-tests) rather than mocked connections.
Code Quality
The package has a dedicated Jest end-to-end test suite (test/controller.spec.ts) that runs the same set of assertions across a matrix of both single-instance and cluster Redis, and both Express and Fastify HTTP adapters, giving reasonably thorough coverage of the actual request-throttling behavior rather than just unit-testing the service in isolation. The increment() method explicitly validates the shape of the Lua script’s return value and throws typed errors if any field isn’t the expected type, rather than silently trusting Redis’s response. ESLint is configured at the monorepo root and extended per-package, and the repository runs CI via GitHub Actions on every push/PR.
What Makes It Unique
Rather than reimplementing rate-limiting logic, this package’s only job is being a well-behaved storage adapter for @nestjs/throttler’s existing interface — its distinguishing technical choice is doing the whole increment-check-block sequence as one atomic Lua script instead of separate INCR/GET/SET calls, which avoids the classic race condition where two concurrent requests both read a stale hit count before either writes back. Native Cluster support (not just single-node Redis) is also handled directly in the same code path via hash-tagged keys, without needing a separate implementation.
Used by 6 apps in this directory
Bigcapital
Invoicing Finance
Self-hostable double-entry accounting platform with invoicing, inventory, multi-currency, and real-time financial reporting for small and medium businesses.
Cal.diy
Scheduling
The 100% MIT-licensed, community-driven scheduling platform — self-host your own booking infrastructure with no enterprise strings attached.
Docmost
Productivity · Note Taking · Collaboration
Self-hosted collaborative wiki and knowledge base with real-time editing, diagrams, AI assistance, and enterprise access controls — a modern alternative to Confluence and Notion.
Ghostfolio
Invoicing Finance
Track your stocks, ETFs, and crypto with a privacy-first, self-hostable wealth management platform built for data-driven investors.
NocoDB
No Code Platforms · Databases · Low Code Platforms
Turn any SQL database into a collaborative no-code spreadsheet with automatic REST APIs and real-time views.
Postiz
Social Media · Automation
The agentic social media scheduler — AI-powered content creation, 33-platform posting, and team workflows, all self-hosted.