npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fluojs/throttler

v1.0.4

Published

Decorator-based rate limiting for Fluo applications with in-memory and Redis store adapters.

Readme

@fluojs/throttler

Decorator-based rate limiting for fluo applications with in-memory and Redis store adapters.

Table of Contents

Installation

@fluojs/throttler declares engines.node >=20.0.0 in its published package manifest.

npm install @fluojs/throttler

When to Use

  • To prevent brute-force attacks on sensitive endpoints (e.g., login, registration).
  • To protect your API from being overwhelmed by too many requests from a single client.
  • To implement usage quotas or tiered rate limits for different types of users.
  • When you need a simple way to apply rate limits using decorators on controllers or methods.

Quick Start

Register the ThrottlerModule, wire ThrottlerGuard with @UseGuards(...), and apply the Throttle decorator to controllers or methods that need route-specific limits.

import { Module } from '@fluojs/core';
import { ThrottlerGuard, ThrottlerModule, Throttle, SkipThrottle } from '@fluojs/throttler';
import { Controller, Post, UseGuards } from '@fluojs/http';

@Module({
  imports: [
    ThrottlerModule.forRoot({
      ttl: 60,   // 60 seconds
      limit: 10, // 10 requests
    }),
  ],
})
class AppModule {}

@Controller('/auth')
@UseGuards(ThrottlerGuard)
class AuthController {
  @Post('/login')
  @Throttle({ ttl: 60, limit: 5 }) // Override: 5 requests per minute
  login() {
    return { success: true };
  }

  @Post('/public-info')
  @SkipThrottle() // Bypass throttling
  getInfo() {
    return { info: '...' };
  }
}

Common Patterns

Redis Storage

For multi-instance deployments, use RedisThrottlerStore to share the rate limit state across all instances. Redis-backed windows are anchored to Redis server time, so distributed app nodes with clock skew still enforce one shared reset boundary.

RedisThrottlerStore accepts the package-local structural RedisThrottlerClient contract: a Redis command client with an eval(script, numberOfKeys, ...args) method. @fluojs/redis, ioredis, and compatible custom clients can be passed without making the root @fluojs/throttler import depend on a concrete ioredis constructor type.

import { ThrottlerModule, RedisThrottlerStore } from '@fluojs/throttler';
import { REDIS_CLIENT } from '@fluojs/redis';

// Inside a provider or module factory
const redisClient = await container.resolve(REDIS_CLIENT);
const redisStore = new RedisThrottlerStore(redisClient);

ThrottlerModule.forRoot({
  ttl: 60,
  limit: 100,
  store: redisStore,
});

You can also pass any object that implements the ThrottlerStore contract through the store option. ThrottlerModule.forRoot(...) validates that a custom store exposes a consume(...) function before request handling starts.

Custom Key Generation

By default, the throttler resolves client identity from the raw socket remoteAddress only. If your deployment sits behind a trusted reverse proxy that rewrites Forwarded, X-Forwarded-For, or X-Real-IP, opt in with trustProxyHeaders: true. If no trusted socket or proxy identity is available, it throws instead of collapsing unrelated callers into a shared bucket. You can also customize this to use API keys, user IDs, or other identifiers.

Counters are scoped by route identity and client identity. The route portion includes method, path, version, and handler identity so different handlers do not share buckets accidentally. When a request is rejected, ThrottlerGuard returns 429 and sets Retry-After.

ThrottlerModule.forRoot({
  ttl: 60,
  limit: 100,
  trustProxyHeaders: true,
});
ThrottlerModule.forRoot({
  ttl: 60,
  limit: 100,
  keyGenerator: (context) => {
    const apiKeyHeader = context.request.headers['x-api-key'];
    const apiKey = Array.isArray(apiKeyHeader) ? apiKeyHeader[0] : apiKeyHeader;

    if (!apiKey) {
      throw new Error('Missing API key for throttler tracking.');
    }

    return `api-key:${apiKey}`;
  },
});

NestJS Migration Boundaries

When migrating from @nestjs/throttler, treat @fluojs/throttler as an explicit guard-stage package rather than a drop-in global limiter:

  • ThrottlerModule.forRoot(...) registers validated options and providers, but it does not automatically enforce throttling on every route. Activate ThrottlerGuard with Fluo guard metadata such as @UseGuards(ThrottlerGuard) wherever enforcement is required.
  • The public policy shape is one module default plus class- or method-level @Throttle({ ttl, limit }) overrides. Named multi-window definitions such as burst plus sustained limits require explicit composition through HTTP middleware, a custom ThrottlerStore, or an application-owned guard wrapper.
  • Forwarded client IP headers are ignored by default. Enable trustProxyHeaders: true only behind a trusted proxy that overwrites Forwarded, X-Forwarded-For, or X-Real-IP.
  • The guaranteed limit-exceeded response contract is HTTP 429 with Retry-After. Additional rate-limit headers or response bodies should be added at the application boundary, for example with an exception filter.

Public API Overview

Modules

  • ThrottlerModule.forRoot(options): Provides validated throttler options and ThrottlerGuard to the module graph.
  • Package-level registration is supported through ThrottlerModule.forRoot(options). Internal provider-composition helpers and DI tokens are not part of the public contract.

ttl and limit must be positive finite integers. global defaults to true; set global: false when the throttler providers should stay scoped to the importing module. trustProxyHeaders and keyGenerator customize client identity; keyGenerator, when provided, must be a function. Module options are validated and captured by value when the guard is wired so later mutation of the caller's options object does not change live throttling policy. If no store option is supplied, each ThrottlerGuard instance owns its own in-memory store; pass a ThrottlerStore implementation such as RedisThrottlerStore when storage must be shared or externally managed.

Decorators

  • @Throttle({ ttl, limit }): Sets a specific rate limit for a class or method.
  • @SkipThrottle(): Disables throttling for a class or method.
  • ThrottlerHandlerOptions: Public { ttl, limit } policy shape accepted by @Throttle(...). Both values must be positive finite integers; method-level policies override class-level policies, which override module defaults.
  • Existing root-barrel metadata helpers (throttleRouteMetadataKey, getThrottleMetadata, getSkipThrottleMetadata, getClassThrottleMetadata, and getClassSkipThrottleMetadata) remain exported for compatibility with advanced integrations that already inspect decorator metadata directly.

Guards

  • ThrottlerGuard: The guard responsible for enforcing rate limits. ThrottlerModule.forRoot() makes it injectable; route handlers still activate it through Fluo guard metadata such as @UseGuards(ThrottlerGuard).

Stores

  • createMemoryThrottlerStore(): Creates a simple in-memory store (default).
  • RedisThrottlerStore: Store adapter for Redis.
  • RedisThrottlerClient: Structural Redis command client contract accepted by RedisThrottlerStore.
  • ThrottlerStore: Public contract for custom stores.
  • ThrottlerConsumeInput: Public input shape passed to ThrottlerStore.consume(key, input) so custom stores can share the guard's current time and TTL window.
  • ThrottlerStoreEntry: Public result shape returned by ThrottlerStore.consume(...); count is the post-consume request count for the active window and resetAt is the epoch-millisecond reset boundary used for Retry-After calculation. Custom stores may return optional retryAfterMs when a backing store has a more authoritative clock than the application process; the guard uses it for Retry-After when the limit is exceeded.

Status and diagnostics

  • createThrottlerPlatformStatusSnapshot(...): Creates a platform status snapshot.
  • createThrottlerPlatformDiagnosticIssues(...): Creates diagnostic issues for invalid throttler state.
  • ThrottlerStatusAdapterInput: Public input shape for status and diagnostic helpers. It carries store kind, ownership mode, operation mode, backing-store readiness, dependency linkage, and readiness criticality hints collected during bootstrap.
  • ThrottlerPlatformStatusSnapshot: Public output shape returned by createThrottlerPlatformStatusSnapshot(...), containing readiness, health, ownership, and details sections compatible with runtime platform snapshots.
  • ThrottlerStoreKind: Store categories recognized by the status adapter: memory, redis, or custom.
  • ThrottlerStoreOwnershipMode: Ownership modes reported in status snapshots: framework for guard-owned resources or external for externally managed stores.
  • ThrottlerOperationMode: Operation modes reported in status details: local-only, distributed, local-fallback, or custom.

Method-level @Throttle(...) overrides class-level settings, class-level settings override module defaults, and @SkipThrottle() bypasses throttling at either class or method level.

Related Packages

  • @fluojs/http: Required for HTTP context and Exception handling.
  • @fluojs/redis: Official Redis client integration for RedisThrottlerStore; ioredis and compatible structural clients are also supported.

Example Sources

  • packages/throttler/src/module.test.ts: Tests for module configuration, decorator overrides, and HTTP guard integration through createTestApp(...).
  • packages/throttler/src/guard.ts: The core logic for request throttling and header management.
  • packages/throttler/src/redis-store.test.ts: Redis store contract and server-time behavior.
  • packages/throttler/src/status.test.ts: Status and diagnostic helper behavior.