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

@aksparadise/valkey-token-bucket

v1.0.0

Published

Production-ready, highly-scalable, and distributed Rate Limiter using Token Bucket algorithm in Valkey/Redis. Prevents race-conditions atomically via Lua scripting. Highly optimized with zero runtime dependencies. Created by AksParadise.

Readme

@aksparadise/valkey-token-bucket ⏱️

NPM Version License Zero Dependencies

A production-ready, highly-scalable, and distributed Token Bucket Rate Limiter for Valkey and Redis in Node.js.

Atomically eliminates distributed race-conditions using high-speed server-side Lua scripts. Zero runtime dependencies for absolute security and safety. Built by AksParadise.


✨ Features

  • 🏎️ Zero-Latency Atomic Evaluation: Recalculates limits inside a single-threaded Lua script on Valkey, preventing concurrency race-conditions (TOCTOU) completely.
  • 🛡️ Zero-Vulnerability Architecture: Has 0 direct runtime dependencies, fully protecting your project from nested package CVE chains.
  • 📦 Dual CJS + ESM Packaging: Supports modern ES6 import syntax as well as legacy CommonJS require() natively.
  • 🔌 Native Driver Support: Out-of-the-box auto-detection for both ioredis and redis (node-redis v4+).
  • 💡 Advanced Express Middleware Wrapper: Built-in, RFC-compliant rate limiter supporting standard headers and custom user dynamic keys (e.g. rate limit by Session Account IDs, API keys, or custom headers).
  • 📐 TypeScript Definitions Included: Fully typed out-of-the-box (d.ts definitions).

📋 Prerequisites

To use this library, ensure your project setup has:

  1. Node.js version 16.0.0 or newer.
  2. Valkey version 7.2.0+ OR Redis version 2.6.0+ (since EVAL execution was introduced).
  3. Either of the following driver clients installed in your project:
    • redis (node-redis version ^4.0.0)
    • ioredis (version ^5.0.0)

🚀 Installation

npm install @aksparadise/valkey-token-bucket

💻 Usage

1. Simple Express Middleware Integration (By Client IP)

By default, the middleware tracks client IP addresses and enforces rate limiting:

import express from "express";
import { createClient } from "redis";
import { expressRateLimiter } from "@aksparadise/valkey-token-bucket";

const app = express();
const redisClient = createClient();
await redisClient.connect();

const limiter = expressRateLimiter({
    redisClient: redisClient,
    capacity: 100,             // Max tokens
    windowMs: 60000,           // Duration to fully refill (1 minute)
    keyPrefix: "limit:api:"
});

// Apply to routes
app.use("/api/v3", limiter);

2. Advanced Express Middleware Integration (By Custom Session User)

You can provide a keyGenerator callback to rate-limit by custom session properties (like logged-in user account IDs or custom auth API keys) rather than client IP addresses:

import express from "express";
import { expressRateLimiter } from "@aksparadise/valkey-token-bucket";

const app = express();

const folderSyncLimiter = expressRateLimiter({
    redisClient: myRedisClient,
    capacity: 10,
    windowMs: 60000,
    keyPrefix: "ratelimit:sync:",
    
    // Custom key resolver:
    keyGenerator: (req) => req.session?.accountId // Defaults to client IP if undefined
});

app.get("/folders", folderSyncLimiter, (req, res) => {
    res.json({ success: true, folders: [] });
});

3. Programmatic Usage (Any Framework)

You can use the core class directly inside any web framework, microservice, gRPC, or WebSocket server:

import { TokenBucketLimiter } from "@aksparadise/valkey-token-bucket";

const limiter = new TokenBucketLimiter({
    redisClient: myRedisClient,
    capacity: 250,
    windowMs: 60000, // 250 requests per minute
    keyPrefix: "api-limit:"
});

async function handleRequest(userId) {
    const result = await limiter.consume(userId, 1);

    if (result.allowed) {
        console.log(`Allowed! Tokens left: ${result.remaining}`);
        // Proceed with request...
    } else {
        console.log(`Rate limited! Retry after ${result.retryAfterSeconds} seconds.`);
        // Return 429 Too Many Requests...
    }
}

📈 Standard HTTP Response Headers

The built-in Express middleware automatically attaches standard RFC-compliant headers:

| Header Name | Description | | :--- | :--- | | X-RateLimit-Limit | The maximum capacity of the rate limit bucket. | | X-RateLimit-Remaining | Remaining tokens left in the bucket. | | Retry-After | Time (in seconds) the client must wait before making another request (returned only on 429). |


🛡️ Security & Fail-Open Philosophy

In enterprise production architectures, a database lag or caching server crash should never lock legitimate users out of your core services.

Our package operates under a strict Fail-Open Policy: if your Valkey or Redis server goes offline or suffers connection timeouts, the library catches the incident, prints a structured warning log console, and silently allows the user request to proceed (calls next()), keeping your user experience 100% seamless during infrastructure updates.


📄 License

MIT © AksParadise