{"id":45165,"library":"ioredis-ratelimit","title":"ioredis-ratelimit","description":"A generic Redis-backed rate limiting tool built on top of ioredis. Current stable version is 3.1.1. Provides three limiting modes (binary, n-ary, uniform), batch operations, dynamic key generation, and minimum interval control. Fully tested with 100% coverage. Designed for Node.js environments with ioredis v5.8.2+. Differentiators include flexible modes, batch operations, and a simple API that can be used as Express middleware or standalone.","status":"active","version":"3.1.1","language":"javascript","source_language":"en","source_url":"https://github.com/nswbmw/ioredis-ratelimit","tags":["javascript","ratelimit","ratelimiter","redis","typescript"],"install":[{"cmd":"npm install ioredis-ratelimit","lang":"bash","label":"npm"},{"cmd":"yarn add ioredis-ratelimit","lang":"bash","label":"yarn"},{"cmd":"pnpm add ioredis-ratelimit","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency: ioredis client instance is required to connect to Redis","package":"ioredis","optional":false}],"imports":[{"note":"Package is ESM-only; CommonJS require will fail.","wrong":"const RateLimiter = require('ioredis-ratelimit')","symbol":"RateLimiter","correct":"import RateLimiter from 'ioredis-ratelimit'"},{"note":"The package exports a single default function.","wrong":"import { RateLimiter } from 'ioredis-ratelimit' // Named import does not exist","symbol":"RateLimiter (default export)","correct":"import RateLimiter from 'ioredis-ratelimit' // default export"},{"note":"Types are bundled with the package; no separate type import is needed.","wrong":"import { RateLimiterOptions } from 'ioredis-ratelimit'","symbol":"RateLimiter (TypeScript type)","correct":"import RateLimiter from 'ioredis-ratelimit' // types are included"}],"quickstart":{"code":"import Redis from 'ioredis'\nimport RateLimiter from 'ioredis-ratelimit'\n\nconst ratelimiter = RateLimiter({\n  client: new Redis(),\n  key: 'my-rate-limiter',\n  limit: 10,\n  duration: 1000\n})\n\n// Check rate limit\nawait ratelimiter()  // { total: 1, acknowledged: 1, remaining: 9 }\n\n// Get current status without consuming\nawait ratelimiter.get()  // { total: 1, remaining: 9, retryAfterMS: 0 }","lang":"typescript","description":"Creates a rate limiter allowing 10 requests per second and demonstrates consuming and checking quota."},"warnings":[{"fix":"Use ES module syntax (import/export) and ensure \"type\": \"module\" in package.json.","message":"Package is ESM-only. Requires Node.js >= 12.22.0 or newer with \"type\": \"module\" in package.json.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Review documentation for mode behavior; consider using 'uniform' mode for smoother limiting.","message":"In mode 'nary', the acknowledged count may not equal requested count if the limit is exceeded in a partial way.","severity":"deprecated","affected_versions":">=2.0.0"},{"fix":"When using key as function, pass id to ratelimiter(id) to generate per-user keys.","message":"The key option must be a string or a function returning a string. If using a function, it receives the id argument passed to ratelimiter().","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Wrap ratelimiter calls in try-catch and return 429 response in Express/other middleware.","message":"The error option is thrown when limit exceeded, but it is not an HTTP-specific error; you must handle HTTP 429 yourself.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Set TTL to duration or do not set it unless you have specific persistence needs.","message":"The TTL option defaults to duration. If you set a longer TTL, the key persists beyond the window, which may cause stale data.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"search_vec":"'100':43 '3.1.1':21 'api':61 'ari':29 'back':8 'batch':31,56 'binari':26 'built':12 'control':39 'coverag':44 'current':17 'design':45 'differenti':52 'dynam':33 'environ':48 'express':67 'flexibl':54 'fulli':40 'generat':35 'generic':5 'includ':53 'interv':38 'ioredi':2,16,50 'ioredis-ratelimit':1 'javascript':71 'key':34 'limit':10,24 'middlewar':68 'minimum':37 'mode':25,55 'n':28 'n-ari':27 'node.js':47 'oper':32,57 'provid':22 'rate':9 'ratelimit':3,72,73 'redi':7,74 'redis-back':6 'simpl':60 'stabl':18 'standalon':70 'test':41 'three':23 'tool':11 'top':14 'typescript':75 'uniform':30 'use':65 'v5.8.2':51 'version':19","created_at":"2026-06-07T12:53:40.550938+00:00","updated_at":"2026-06-07T12:53:40.550938+00:00","problems":[{"fix":"Add 'type': 'module' to package.json, or use dynamic import().","cause":"Package is ESM-only, but project uses CommonJS (require) or missing 'type':'module'.","error":"SyntaxError: Cannot use import statement outside a module"},{"fix":"Use: import RateLimiter from 'ioredis-ratelimit'","cause":"Using named import { RateLimiter } instead of default import.","error":"TypeError: RateLimiter is not a function"},{"fix":"Catch the error and respond with appropriate status (e.g., 429 HTTP status). Customize via error option.","cause":"Rate limit exceeded; default error thrown.","error":"Error: Too Many Requests"},{"fix":"Call RateLimiter({...}) without new since it's a factory function.","cause":"Using new RateLimiter() instead of calling as a function.","error":"RateLimiter is not a constructor"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":null,"cli_version":null,"type":"library","homepage":"https://github.com/nswbmw/ioredis-ratelimit#readme","github":"https://github.com/nswbmw/ioredis-ratelimit","docs":null,"changelog":null,"pypi":null,"npm":"ioredis-ratelimit","openapi_spec":null,"status_page":null,"smithery":null,"categories":["devops"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-07","next_check":"2026-09-05","install_tag":null}}