{"id":24299138,"url":"https://github.com/mehrantsi/hyperlimit","last_synced_at":"2026-04-11T13:34:51.007Z","repository":{"id":272687528,"uuid":"916297949","full_name":"mehrantsi/hyperlimit","owner":"mehrantsi","description":"High-performance native rate limiter for Node.js","archived":false,"fork":false,"pushed_at":"2025-10-15T11:50:41.000Z","size":289,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-16T05:07:58.474Z","etag":null,"topics":["fastify","hyperexpress","nodejs","npm","npm-package","rate-limiter","ratelimiter"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mehrantsi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-01-13T20:35:27.000Z","updated_at":"2025-10-15T11:50:37.000Z","dependencies_parsed_at":null,"dependency_job_id":"ba50878c-8dc1-49f4-8d22-e846167e941f","html_url":"https://github.com/mehrantsi/hyperlimit","commit_stats":null,"previous_names":["mehrantsi/hyperlimit"],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/mehrantsi/hyperlimit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mehrantsi%2Fhyperlimit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mehrantsi%2Fhyperlimit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mehrantsi%2Fhyperlimit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mehrantsi%2Fhyperlimit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mehrantsi","download_url":"https://codeload.github.com/mehrantsi/hyperlimit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mehrantsi%2Fhyperlimit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31682953,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-11T13:07:20.380Z","status":"ssl_error","status_checked_at":"2026-04-11T13:06:47.903Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fastify","hyperexpress","nodejs","npm","npm-package","rate-limiter","ratelimiter"],"created_at":"2025-01-16T21:18:52.704Z","updated_at":"2026-04-11T13:34:50.974Z","avatar_url":"https://github.com/mehrantsi.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# HyperLimit\n\n[![npm version](https://badge.fury.io/js/%40hyperlimit%2Fcore.svg)](https://badge.fury.io/js/%40hyperlimit%2Fcore)\n[![Build and Release](https://github.com/mehrantsi/hyperlimit/actions/workflows/build.yml/badge.svg)](https://github.com/mehrantsi/hyperlimit/actions/workflows/build.yml)\n[![Test](https://github.com/mehrantsi/hyperlimit/actions/workflows/test.yml/badge.svg)](https://github.com/mehrantsi/hyperlimit/actions/workflows/test.yml)\n[![CodeQL](https://github.com/mehrantsi/hyperlimit/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/mehrantsi/hyperlimit/actions/workflows/github-code-scanning/codeql)\n\nHigh-performance native rate limiter for Node.js with lock-free design, optimized for high-throughput applications. Capable of processing over 9 million requests per second in synthetic benchmarks.\n\n## Features\n\n- Lock-free design for high concurrency\n- Per-key rate limiting with configurable windows\n- Memory-efficient implementation\n- Thread-safe operations\n- Sliding window support\n- Multiple independent rate limiters\n- Real-time monitoring and statistics\n- Distributed rate limiting (Redis or NATS)\n- Dynamic rate limiting per tenant/API key\n- Bypass keys for trusted clients\n- Penalty system for abuse prevention\n- Customizable key generation\n- Framework-specific middleware packages\n\n## Installation\n\nChoose the package that matches your framework:\n\n```bash\n# For Express.js\nnpm install @hyperlimit/express\n\n# For Fastify\nnpm install @hyperlimit/fastify\n\n# For HyperExpress\nnpm install @hyperlimit/hyperexpress\n\n# Core package (if you want to build custom middleware)\nnpm install hyperlimit\n```\n\n## Basic Usage\n\n### Express.js\n\n```javascript\nconst express = require('express');\nconst rateLimiter = require('@hyperlimit/express');\n\nconst app = express();\n\n// Example routes using direct configuration\napp.get('/api/public', rateLimiter({\n    key: 'public',\n    maxTokens: 100,\n    window: '1m',\n    sliding: true,\n    block: '30s'\n}), (req, res) =\u003e {\n    res.json({ message: 'Public API response' });\n});\n\n// Protected route with more options\napp.get('/api/protected', rateLimiter({\n    key: 'protected',\n    maxTokens: 5,\n    window: '1m',\n    sliding: true,\n    block: '5m',\n    maxPenalty: 3,\n    onRejected: (req, res, info) =\u003e {\n        res.status(429).json({\n            error: 'Rate limit exceeded',\n            message: 'Please try again later',\n            retryAfter: info.retryAfter\n        });\n    }\n}), (req, res) =\u003e {\n    res.json({ message: 'Protected API response' });\n});\n\n// Custom rate limit with bypass keys\napp.get('/api/custom', rateLimiter({\n    key: 'custom',\n    maxTokens: 20,\n    window: '30s',\n    sliding: true,\n    block: '1m',\n    keyGenerator: req =\u003e `${req.ip}-${req.query.userId}`,\n    bypassHeader: 'X-Custom-Key',\n    bypassKeys: ['special-key']\n}), (req, res) =\u003e {\n    res.json({ message: 'Custom API response' });\n});\n\n// Distributed rate limiting with NATS\napp.get('/api/distributed', rateLimiter({\n    key: 'distributed',\n    maxTokens: 100,\n    window: '1m',\n    nats: {\n        servers: 'nats://localhost:4222',\n        bucket: 'rate-limits',\n        prefix: 'rl_'\n    }\n}), (req, res) =\u003e {\n    res.json({ message: 'Distributed API response' });\n});\n```\n\n### Fastify\n\n```javascript\nconst fastify = require('fastify')();\nconst rateLimiter = require('@hyperlimit/fastify');\n\nfastify.get('/api/public', {\n    preHandler: rateLimiter({\n        key: 'public',\n        maxTokens: 100,\n        window: '1m',\n        sliding: true,\n        block: '30s'\n    }),\n    handler: async (request, reply) =\u003e {\n        return { message: 'Public API response' };\n    }\n});\n\n// Protected route with more options\nfastify.get('/api/protected', {\n    preHandler: rateLimiter({\n        key: 'protected',\n        maxTokens: 5,\n        window: '1m',\n        sliding: true,\n        block: '5m',\n        maxPenalty: 3,\n        onRejected: (request, reply, info) =\u003e {\n            reply.code(429).send({\n                error: 'Rate limit exceeded',\n                message: 'Please try again later',\n                retryAfter: info.retryAfter\n            });\n        }\n    }),\n    handler: async (request, reply) =\u003e {\n        return { message: 'Protected API response' };\n    }\n});\n\n// Custom rate limit with bypass keys\nfastify.get('/api/custom', {\n    preHandler: rateLimiter({\n        key: 'custom',\n        maxTokens: 20,\n        window: '30s',\n        sliding: true,\n        block: '1m',\n        keyGenerator: req =\u003e `${req.ip}-${req.query.userId}`,\n        bypassHeader: 'X-Custom-Key',\n        bypassKeys: ['special-key']\n    }),\n    handler: async (request, reply) =\u003e {\n        return { message: 'Custom API response' };\n    }\n});\n\n// Distributed rate limiting with NATS\nfastify.get('/api/distributed', {\n    preHandler: rateLimiter({\n        key: 'distributed',\n        maxTokens: 100,\n        window: '1m',\n        nats: {\n            servers: 'nats://localhost:4222',\n            bucket: 'rate-limits',\n            prefix: 'rl_'\n        }\n    }),\n    handler: async (request, reply) =\u003e {\n        return { message: 'Distributed API response' };\n    }\n});\n```\n\n### HyperExpress\n\n```javascript\nconst HyperExpress = require('hyper-express');\nconst rateLimiter = require('@hyperlimit/hyperexpress');\n\nconst app = new HyperExpress.Server();\n\napp.get('/api/public', rateLimiter({\n    key: 'public',\n    maxTokens: 100,\n    window: '1m',\n    sliding: true,\n    block: '30s'\n}), (req, res) =\u003e {\n    res.json({ message: 'Public API response' });\n});\n\n// Protected route with more options\napp.get('/api/protected', rateLimiter({\n    key: 'protected',\n    maxTokens: 5,\n    window: '1m',\n    sliding: true,\n    block: '5m',\n    maxPenalty: 3,\n    onRejected: (req, res, info) =\u003e {\n        res.status(429);\n        res.json({\n            error: 'Rate limit exceeded',\n            message: 'Please try again later',\n            retryAfter: info.retryAfter\n        });\n    }\n}), (req, res) =\u003e {\n    res.json({ message: 'Protected API response' });\n});\n\n// Custom rate limit with bypass keys\napp.get('/api/custom', rateLimiter({\n    key: 'custom',\n    maxTokens: 20,\n    window: '30s',\n    sliding: true,\n    block: '1m',\n    keyGenerator: req =\u003e `${req.ip}-${req.query.userId}`,\n    bypassHeader: 'X-Custom-Key',\n    bypassKeys: ['special-key']\n}), (req, res) =\u003e {\n    res.json({ message: 'Custom API response' });\n});\n\n// Distributed rate limiting with NATS\napp.get('/api/distributed', rateLimiter({\n    key: 'distributed',\n    maxTokens: 100,\n    window: '1m',\n    nats: {\n        servers: 'nats://localhost:4222',\n        bucket: 'rate-limits',\n        prefix: 'rl_'\n    }\n}), (req, res) =\u003e {\n    res.json({ message: 'Distributed API response' });\n});\n```\n\n### Core Package Usage\n\nFor custom middleware or direct usage:\n\n```javascript\nconst { HyperLimit } = require('hyperlimit');\n\n// Create a rate limiter instance\nconst limiter = new HyperLimit({\n    bucketCount: 16384  // Optional: number of hash table buckets (default: 16384)\n});\n\n// Create a limiter for a specific endpoint/feature\nlimiter.createLimiter(\n    'api:endpoint1',    // Unique identifier for this limiter\n    100,               // maxTokens: Maximum requests allowed\n    60000,             // window: Time window in milliseconds\n    true,              // sliding: Use sliding window\n    30000,             // block: Block duration in milliseconds\n    5                  // maxPenalty: Maximum penalty points\n);\n\n// Example usage in custom middleware\nfunction customRateLimiter(options = {}) {\n    const limiter = new HyperLimit();\n    const defaultKey = 'default';\n    \n    // Create the limiter with options\n    limiter.createLimiter(\n        defaultKey,\n        options.maxTokens || 100,\n        typeof options.window === 'string' \n            ? parseDuration(options.window) \n            : (options.window || 60000),\n        options.sliding !== false,\n        typeof options.block === 'string'\n            ? parseDuration(options.block)\n            : (options.block || 0),\n        options.maxPenalty || 0\n    );\n\n    // Return middleware function\n    return function(req, res, next) {\n        const key = options.keyGenerator?.(req) || req.ip;\n        const allowed = limiter.tryRequest(key);\n\n        if (!allowed) {\n            const info = limiter.getRateLimitInfo(key);\n            return res.status(429).json({\n                error: 'Too many requests',\n                retryAfter: Math.ceil(info.reset / 1000)\n            });\n        }\n\n        // Attach limiter to request for later use\n        req.rateLimit = { limiter, key };\n        next();\n    };\n}\n\n// Helper to parse time strings (e.g., '1m', '30s')\nfunction parseDuration(timeStr) {\n    const units = { ms: 1, s: 1000, m: 60000, h: 3600000, d: 86400000 };\n    const match = timeStr.match(/^(\\d+)([a-z]+)$/i);\n    if (!match) return parseInt(timeStr, 10);\n    const [, num, unit] = match;\n    return parseInt(num, 10) * (units[unit] || units.ms);\n}\n```\n\n## Advanced Features\n\n### 1. Dynamic Configuration with configResolver\n\nUse `configResolver` for dynamic, per-request rate limit configuration. This is ideal for multi-tenant applications where different clients have different rate limits:\n\n```javascript\nconst express = require('express');\nconst rateLimit = require('@hyperlimit/express');\n\n// Example: Dynamic rate limits based on API key\napp.use(rateLimit({\n    keyGenerator: (req) =\u003e req.headers['x-api-key'] || 'anonymous',\n    \n    // Called on each request to determine rate limit config\n    configResolver: (apiKey) =\u003e {\n        // Look up the configuration for this API key\n        const userTier = getUserTier(apiKey);\n        \n        switch(userTier) {\n            case 'premium':\n                return {\n                    maxTokens: 1000,\n                    window: '1h',\n                    sliding: true\n                };\n            case 'basic':\n                return {\n                    maxTokens: 100,\n                    window: '15m',\n                    sliding: true\n                };\n            default:\n                // Unknown keys get minimal access\n                return {\n                    maxTokens: 10,\n                    window: '1h',\n                    sliding: true\n                };\n        }\n    },\n    \n    // Use distributed storage for multi-instance deployments\n    nats: {\n        servers: 'nats://localhost:4222',\n        bucket: 'rate-limits',\n        prefix: 'rl_'\n    }\n}));\n```\n\nThe `configResolver` is called with the key from `keyGenerator` and should return a configuration object. Return `null` or a config with `maxTokens: 0` to deny access.\n\n### 2. Tenant-Based Rate Limiting\n\nPerfect for SaaS applications with different tiers of service:\n\n```javascript\n// Simulating a database of tenant configurations\nconst tenantConfigs = new Map();\nconst tenantLimiters = new Map();\n\n// Example tenant configurations\ntenantConfigs.set('tenant1-key', {\n    name: 'Basic Tier',\n    endpoints: {\n        '/api/data': { maxTokens: 5, window: '10s' },\n        '/api/users': { maxTokens: 2, window: '10s' },\n        '*': { maxTokens: 10, window: '60s' } // Default for unspecified endpoints\n    }\n});\n\ntenantConfigs.set('tenant2-key', {\n    name: 'Premium Tier',\n    endpoints: {\n        '/api/data': { maxTokens: 20, window: '10s' },\n        '/api/users': { maxTokens: 10, window: '10s' },\n        '*': { maxTokens: 50, window: '60s' }\n    }\n});\n\n// Helper to get or create rate limiter for tenant+endpoint\nfunction getTenantLimiter(tenantKey, endpoint) {\n    const cacheKey = `${tenantKey}:${endpoint}`;\n    \n    if (tenantLimiters.has(cacheKey)) {\n        return tenantLimiters.get(cacheKey);\n    }\n\n    const tenantConfig = tenantConfigs.get(tenantKey);\n    if (!tenantConfig) {\n        return null;\n    }\n\n    // Get endpoint specific config or fallback to default\n    const config = tenantConfig.endpoints[endpoint] || tenantConfig.endpoints['*'];\n    if (!config) {\n        return null;\n    }\n\n    const limiter = rateLimiter({\n        maxTokens: config.maxTokens,\n        window: config.window,\n        keyGenerator: (req) =\u003e req.headers['x-api-key']\n    });\n\n    tenantLimiters.set(cacheKey, limiter);\n    return limiter;\n}\n\n// Tenant authentication middleware\nfunction authenticateTenant(req, res, next) {\n    const apiKey = req.headers['x-api-key'];\n    if (!apiKey) {\n        return res.status(401).json({ error: 'API key required' });\n    }\n\n    const config = tenantConfigs.get(apiKey);\n    if (!config) {\n        return res.status(401).json({ error: 'Invalid API key' });\n    }\n\n    req.tenant = {\n        apiKey,\n        config\n    };\n    next();\n}\n\n// Dynamic rate limiting middleware\nfunction dynamicRateLimit(req, res, next) {\n    const limiter = getTenantLimiter(req.tenant.apiKey, req.path);\n    if (!limiter) {\n        return res.status(500).json({ error: 'Rate limiter configuration error' });\n    }\n    \n    return limiter(req, res, next);\n}\n\n// Apply tenant authentication to all routes\napp.use(authenticateTenant);\n\n// API endpoints with dynamic rate limiting\napp.get('/api/data', dynamicRateLimit, (req, res) =\u003e {\n    res.json({\n        message: 'Data endpoint',\n        tenant: req.tenant.config.name,\n        path: req.path\n    });\n});\n```\n\n### 2. Distributed Rate Limiting\n\nFor applications running across multiple servers:\n\n```javascript\nconst { HyperLimit } = require('hyperlimit');\n\n// Create HyperLimit instance with Redis support\nconst limiter = new HyperLimit({\n    bucketCount: 16384,\n    redis: {\n        host: 'localhost',\n        port: 6379,\n        prefix: 'rl:'\n    }\n});\n\n// Configure rate limiter with a distributed key for global coordination\nlimiter.createLimiter(\n    'api:endpoint1',      // Local identifier\n    100,                  // Total allowed requests across all servers\n    60000,               // 1 minute window\n    true,                // Use sliding window\n    0,                   // No block duration\n    0,                   // No penalties\n    'api:endpoint1:global' // Distributed key for Redis\n);\n\n// Use in your application\napp.get('/api/endpoint', (req, res) =\u003e {\n    const allowed = limiter.tryRequest('api:endpoint1');\n    if (!allowed) {\n        const info = limiter.getRateLimitInfo('api:endpoint1');\n        return res.status(429).json({\n            error: 'Rate limit exceeded',\n            retryAfter: Math.ceil(info.reset / 1000)\n        });\n    }\n    res.json({ message: 'Success' });\n});\n\n// Or use with middleware\napp.get('/api/endpoint', rateLimiter({\n    key: 'api:endpoint1',\n    maxTokens: 100,\n    window: '1m',\n    sliding: true,\n    redis: {\n        host: 'localhost',\n        port: 6379,\n        prefix: 'rl:'\n    }\n}), (req, res) =\u003e {\n    res.json({ message: 'Success' });\n});\n```\n\nWhen Redis is configured:\n- Rate limits are synchronized across all application instances\n- Tokens are stored and managed in Redis\n- Automatic fallback to local rate limiting if Redis is unavailable\n- Atomic operations ensure consistency\n- Minimal latency overhead\n\nRedis configuration options:\n```javascript\n{\n    host: 'localhost',      // Redis host\n    port: 6379,            // Redis port\n    password: 'optional',   // Redis password\n    db: 0,                 // Redis database number\n    prefix: 'rl:',         // Key prefix for rate limit data\n    connectTimeout: 10000,  // Connection timeout in ms\n    maxRetriesPerRequest: 3 // Max retries per request\n}\n```\n\n### 3. Penalty System\n\nHandle abuse and violations:\n\n```javascript\napp.post('/api/sensitive', limiter, (req, res) =\u003e {\n    if (violationDetected) {\n        // Add penalty points\n        req.rateLimit.limiter.addPenalty(req.rateLimit.key, 2);\n        return res.status(400).json({ error: 'Violation detected' });\n    }\n    \n    // Later, can remove penalties\n    req.rateLimit.limiter.removePenalty(req.rateLimit.key, 1);\n});\n```\n\n### 4. Monitoring and Statistics\n\nTrack rate limiting status:\n\n```javascript\napp.get('/status', (req, res) =\u003e {\n    const info = req.rateLimit.limiter.getRateLimitInfo(req.rateLimit.key);\n    res.json({\n        limit: info.limit,\n        remaining: info.remaining,\n        reset: info.reset,\n        blocked: info.blocked\n    });\n});\n```\n\n### 5. Redis Integration Details\n\nWhen Redis is configured:\n- Rate limits are synchronized across all application instances\n- Tokens are stored and managed in Redis\n- Automatic fallback to local rate limiting if Redis is unavailable\n- Atomic operations ensure consistency\n- Minimal latency overhead\n\nRedis configuration options:\n```javascript\n{\n    host: 'localhost',      // Redis host\n    port: 6379,            // Redis port\n    password: 'optional',   // Redis password\n    db: 0,                 // Redis database number\n    prefix: 'rl:',         // Key prefix for rate limit data\n    connectTimeout: 10000,  // Connection timeout in ms\n    maxRetriesPerRequest: 3 // Max retries per request\n}\n```\n\n### 6. NATS Integration (Alternative to Redis)\n\nHyperLimit also supports NATS as a distributed storage backend, offering:\n- Lightweight, high-performance messaging\n- Built-in persistence with JetStream\n- Native support for distributed architectures\n- Lower operational overhead than Redis\n- Built-in security features (TLS, authentication)\n\n**Prerequisites:**\n1. **NATS server with JetStream enabled**\n   - Quick start: `docker run -p 4222:4222 nats:latest -js`\n   - The `-js` flag is required to enable JetStream for KV storage\n\n2. **NATS C client library (cnats) - REQUIRED**\n   - macOS: `brew install cnats`\n   - Ubuntu/Debian: `apt-get install libnats-dev`\n   - Windows: `vcpkg install cnats`\n   \n   **Important**: The cnats library must be installed on your system for NATS integration to work. HyperLimit uses dynamic library loading to interface with NATS.\n\nNATS configuration:\n```javascript\nconst limiter = new HyperLimit({\n    bucketCount: 16384,\n    nats: {\n        servers: 'nats://localhost:4222',  // Single server or array\n        bucket: 'rate-limits',              // KV bucket name\n        prefix: 'rl_',                      // Key prefix\n        credentials: './nats.creds'         // Optional auth file\n    }\n});\n```\n\nNATS configuration options:\n```javascript\n{\n    servers: string | string[],  // NATS server(s)\n    bucket: string,              // KV bucket name for rate limit data\n    prefix: string,              // Key prefix (default: 'rl_')\n    credentials?: string         // Path to NATS credentials file\n}\n```\n\nExample with NATS cluster:\n```javascript\nconst limiter = new HyperLimit({\n    bucketCount: 16384,\n    nats: {\n        servers: [\n            'nats://nats1.example.com:4222',\n            'nats://nats2.example.com:4222',\n            'nats://nats3.example.com:4222'\n        ],\n        bucket: 'rate-limits',\n        prefix: 'rl_'\n    }\n});\n```\n\n## Configuration Options\n\n```typescript\ninterface RateLimiterOptions {\n    // Core Options\n    maxTokens: number;      // Maximum requests allowed\n    window: string|number;  // Time window (e.g., '1m', '30s', or milliseconds)\n    sliding?: boolean;      // Use sliding window (default: true)\n    block?: string|number;  // Block duration after limit exceeded\n    \n    // Advanced Options\n    maxPenalty?: number;     // Maximum penalty points\n    bypassHeader?: string;   // Header for bypass keys\n    bypassKeys?: string[];   // List of bypass keys\n    keyGenerator?: (req) =\u003e string;  // Custom key generation\n    \n    // Distributed Options\n    redis?: Redis;           // Redis client for distributed mode\n    nats?: NatsOptions;      // NATS configuration for distributed mode\n    \n    // Response Handling\n    onRejected?: (req, res, info) =\u003e void;  // Custom rejection handler\n    \n    // Dynamic Configuration\n    configResolver?: (key: string) =\u003e {    // Dynamic config resolution\n        maxTokens: number;\n        window: string;\n        sliding?: boolean;\n        block?: string;\n        maxPenalty?: number;\n    } | null;\n}\n```\n\n## Response Headers\n\nThe middleware automatically sets these headers:\n- `X-RateLimit-Limit`: Maximum allowed requests\n- `X-RateLimit-Remaining`: Remaining requests in window\n- `X-RateLimit-Reset`: Seconds until limit resets\n\n## Performance Benchmarks\n\nHyperLimit achieves exceptional performance through:\n- Native C++ implementation\n- Lock-free atomic operations\n- No external dependencies\n- Efficient token bucket algorithm\n- Minimal memory footprint\n\n| Test Type | Requests/sec | Latency (ms) |\n|-----------|-------------|--------------|\n| Single Key | ~9.1M | 0.11 |\n| Multi-Key | ~7.5M | 0.13 |\n| Concurrent | ~3.2M | 0.31 |\n\n### Detailed Benchmark Results\n\nTests performed on a MacBook Pro with Apple M3 Max, 64GB RAM. Each test measures:\n- Single Key: Processing 1,000,000 requests through a single key\n- Multi-Key: Processing 100,000 requests with unique keys\n- Concurrent: Processing 100,000 concurrent requests with unique keys\n\n#### Small Hash Table (1K)\n\n| Test Type | HyperLimit | Rate Limiter Flexible | Express Rate Limit | Req/sec (HyperLimit) |\n|-----------|------------|----------------------|-------------------|---------------------|\n| Single Key | 109.887ms | 176.971ms | 8.359s | ~9.1M |\n| Multi-Key | 14.747ms | 90.725ms | 906.47ms | ~6.8M |\n| Concurrent | 30.99ms | 96.715ms | 995.496ms | ~3.2M |\n\n#### Default Hash Table (16K)\n\n| Test Type | HyperLimit | Rate Limiter Flexible | Express Rate Limit | Req/sec (HyperLimit) |\n|-----------|------------|----------------------|-------------------|---------------------|\n| Single Key | 106.497ms | 174.073ms | 9.338s | ~9.4M |\n| Multi-Key | 13.311ms | 84.9ms | 985.935ms | ~7.5M |\n| Concurrent | 34.857ms | 101.525ms | 986.597ms | ~2.9M |\n\n#### Large Hash Table (64K)\n\n| Test Type | HyperLimit | Rate Limiter Flexible | Express Rate Limit | Req/sec (HyperLimit) |\n|-----------|------------|----------------------|-------------------|---------------------|\n| Single Key | 109.467ms | 184.259ms | 9.374s | ~9.1M |\n| Multi-Key | 12.12ms | 77.029ms | 935.926ms | ~8.3M |\n| Concurrent | 34.236ms | 90.011ms | 1.079s | ~2.9M |\n\nKey findings:\n- Up to 85x faster than Express Rate Limit\n- Up to 7x faster than Rate Limiter Flexible\n- Consistent performance across different hash table sizes\n- Exceptional multi-key and concurrent performance\n- Sub-millisecond latency in most scenarios\n\nNote: These are synthetic benchmarks measuring raw performance without network overhead or real-world conditions. Actual performance will vary based on your specific use case and environment.\n\n## Examples\n\nCheck out the [examples](./examples) directory for:\n- Basic rate limiting setups\n- Tenant-based configurations\n- Distributed rate limiting\n- Penalty system implementation\n- Monitoring and statistics\n- Custom key generation\n- Framework-specific implementations\n\n## Best Practices\n\n1. **Key Generation**:\n   - Use meaningful keys (e.g., `${req.ip}-${req.path}`)\n   - Consider user identity for authenticated routes\n   - Combine multiple factors for granular control\n\n2. **Window Selection**:\n   - Use sliding windows for smooth rate limiting\n   - Match window size to endpoint sensitivity\n   - Consider user experience when setting limits\n\n3. **Distributed Setup**:\n   - Enable Redis for multi-server deployments\n   - Set appropriate prefix to avoid key collisions\n   - Monitor Redis connection health\n\n4. **Penalty System**:\n   - Start with small penalties\n   - Implement gradual penalty removal\n   - Log penalty events for analysis\n\n5. **Monitoring**:\n   - Regularly check rate limit status\n   - Monitor bypass key usage\n   - Track penalty patterns\n\n## Prerequisites for Distributed Rate Limiting\n\n### Redis (Option 1)\n- Redis server (any version supporting Lua scripts)\n- Install: `docker run -p 6379:6379 redis:latest`\n\n### NATS (Option 2)\n- NATS server with JetStream enabled\n- Install: `docker run -p 4222:4222 nats:latest -js`\n- C client library (libnats) - **REQUIRED**:\n  - macOS: `brew install cnats`\n  - Ubuntu/Debian: `apt-get install libnats-dev`\n  - Windows: Use vcpkg `vcpkg install cnats`\n\n## Troubleshooting\n\n### NATS Integration Issues\n\n#### \"NATS connection failed\" Error\n1. **Verify cnats is installed**: Run `brew list cnats` (macOS) or `dpkg -l libnats-dev` (Ubuntu)\n2. **Check NATS server is running**: `nats server check`\n3. **Ensure JetStream is enabled**: The server must be started with `-js` flag\n\n#### \"Failed to create/bind to KV store\" Error\nThis generic error can occur for several reasons:\n\n1. **JetStream permissions**: Your NATS user may lack permissions to create buckets. Try:\n   - Creating the bucket manually: `nats kv add rate-limits --ttl=1h`\n   - Or ensure your user has JetStream admin permissions\n\n2. **JetStream initialization**: After starting NATS, wait a few seconds before connecting\n\n3. **Bucket conflicts**: Delete and recreate the bucket:\n   ```bash\n   nats kv rm rate-limits -f\n   nats kv add rate-limits --ttl=1h\n   ```\n\n4. **Connection issues**: Test with NATS CLI:\n   ```bash\n   nats kv put rate-limits test \"value\"\n   nats kv get rate-limits test\n   ```\n\n#### Dynamic Library Loading Issues\nIf HyperLimit can't find the cnats library:\n- **macOS**: Ensure `/usr/local/lib` or `/opt/homebrew/lib` is in your library path\n- **Linux**: Run `sudo ldconfig` after installing libnats-dev\n- **Windows**: Ensure nats.dll is in your PATH\n\n## Building from Source\n\n```bash\n# Clone the repository\ngit clone https://github.com/mehrantsi/hyperlimit.git\n\n# Install dependencies\ncd hyperlimit\nnpm install\n\n# Build\nnpm run build\n\n# Run tests\nnpm test\n\n# Run examples\nnpm run example:express\nnpm run example:fastify\nnpm run example:hyperexpress\n```\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request. See [CONTRIBUTING.md](./CONTRIBUTING.md) for more information.\n\n## License\n\nMIT License - see LICENSE file for details\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmehrantsi%2Fhyperlimit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmehrantsi%2Fhyperlimit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmehrantsi%2Fhyperlimit/lists"}