@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.

Library
npm
v1.2.0
126stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
42/100Fair
Development Activity4
Maintenance32
Community56
Maturity56
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
73/100Good
Architecture80
Code Quality78
Innovation60
Learning Curve75

@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 ThrottlerStorageRedisService class implementing @nestjs/throttler’s ThrottlerStorage interface, ready to pass into ThrottlerModule.forRoot/forRootAsync
  • Flexible construction: pass nothing (defaults to localhost:6379), a connection URL string, an existing ioredis Redis/Cluster instance, or a RedisOptions object
  • 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 OnModuleDestroy lifecycle 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-dockerwait-for-dockerrun-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

TypeScript
97%
AGPL 3.0

Bigcapital

Invoicing Finance

3,884

Self-hostable double-entry accounting platform with invoicing, inventory, multi-currency, and real-time financial reporting for small and medium businesses.

View details
91
Repo Health
77
Technical
61
Dependency
Built with
TypeScript97%
Updated yesterday
TypeScript
96%
Other

Cal.diy

Scheduling

48,218

The 100% MIT-licensed, community-driven scheduling platform — self-host your own booking infrastructure with no enterprise strings attached.

View details
95
Repo Health
86
Technical
65
Dependency
Built with
TypeScript96%
Updated yesterday
TypeScript
95%
AGPL 3.0

Docmost

Productivity · Note Taking · Collaboration

21,600

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.

View details
89
Repo Health
70
Technical
70
Dependency
Built with
TypeScript95%
Updated yesterday
TypeScript
76%
AGPL 3.0

Ghostfolio

Invoicing Finance

9,252

Track your stocks, ETFs, and crypto with a privacy-first, self-hostable wealth management platform built for data-driven investors.

View details
93
Repo Health
79
Technical
67
Dependency
Built with
TypeScript76%
HTML21%
Updated yesterday
TypeScript
64%
Other

NocoDB

No Code Platforms · Databases · Low Code Platforms

64,861

Turn any SQL database into a collaborative no-code spreadsheet with automatic REST APIs and real-time views.

View details
90
Repo Health
77
Technical
62
Dependency
Built with
TypeScript64%
Vue31%
Updated 2 days ago
TypeScript
79%
AGPL 3.0

Postiz

Social Media · Automation

35,528

The agentic social media scheduler — AI-powered content creation, 33-platform posting, and team workflows, all self-hosted.

View details
91
Repo Health
70
Technical
63
Dependency
Built with
TypeScript79%
JavaScript12%
Updated 3 days 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

Search