{"id":13454950,"url":"https://github.com/animir/node-rate-limiter-flexible","last_synced_at":"2025-05-06T02:46:49.613Z","repository":{"id":32354787,"uuid":"132330004","full_name":"animir/node-rate-limiter-flexible","owner":"animir","description":"Atomic counters and rate limiting tools. Limit resource access at any scale.","archived":false,"fork":false,"pushed_at":"2025-04-28T20:30:40.000Z","size":1206,"stargazers_count":3235,"open_issues_count":18,"forks_count":168,"subscribers_count":22,"default_branch":"master","last_synced_at":"2025-05-01T15:18:05.007Z","etag":null,"topics":["bruteforce","dynamodb","express","hapi","koa","limit","nestjs","postgresql","prisma","rate-limiting","ratelimter","redis","security","sqlite","throttle","valkey"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/animir.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"ko_fi":"animir","patreon":"animir"}},"created_at":"2018-05-06T10:56:11.000Z","updated_at":"2025-05-01T11:19:24.000Z","dependencies_parsed_at":"2024-01-12T00:28:11.475Z","dependency_job_id":"ada4ab6a-cc1e-4fa0-acd4-1396e22e5f5e","html_url":"https://github.com/animir/node-rate-limiter-flexible","commit_stats":{"total_commits":616,"total_committers":44,"mean_commits":14.0,"dds":0.4025974025974026,"last_synced_commit":"661d794212441f104a6941092c28805b3bd76537"},"previous_names":[],"tags_count":48,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/animir%2Fnode-rate-limiter-flexible","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/animir%2Fnode-rate-limiter-flexible/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/animir%2Fnode-rate-limiter-flexible/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/animir%2Fnode-rate-limiter-flexible/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/animir","download_url":"https://codeload.github.com/animir/node-rate-limiter-flexible/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252612443,"owners_count":21776252,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["bruteforce","dynamodb","express","hapi","koa","limit","nestjs","postgresql","prisma","rate-limiting","ratelimter","redis","security","sqlite","throttle","valkey"],"created_at":"2024-07-31T08:00:59.699Z","updated_at":"2025-05-06T02:46:49.606Z","avatar_url":"https://github.com/animir.png","language":"JavaScript","readme":"[![npm version](https://badge.fury.io/js/rate-limiter-flexible.svg)](https://www.npmjs.com/package/rate-limiter-flexible)\n![npm](https://img.shields.io/npm/dm/rate-limiter-flexible.svg)\n[![node version][node-image]][node-url]\n[![deno version](https://img.shields.io/badge/deno-^1.5.3-lightgrey?logo=deno)](https://github.com/denoland/deno)\n\n[node-image]: https://img.shields.io/badge/node.js-%3E=_20.0-green.svg?style=flat-square\n[node-url]: http://nodejs.org/download/\n\n\u003cimg src=\"img/rlflx-logo-small.png\" width=\"50\" alt=\"Logo\"/\u003e\n\n## node-rate-limiter-flexible\n\n**rate-limiter-flexible** counts and limits the number of actions by key and protects from DDoS and brute force attacks at any scale.\n\nIt works with _Valkey_, _Redis_, _Prisma_, _DynamoDB_, process _Memory_, _Cluster_ or _PM2_, _Memcached_, _MongoDB_, _MySQL_, _SQLite_, and _PostgreSQL_.\n\nMemory limiter also works in the browser.\n\n**Atomic increments.** All operations in memory or distributed environment use atomic increments against race conditions.\n\n**Fast.** Average request takes `0.7ms` in Cluster and `2.5ms` in Distributed application. See [benchmarks](https://github.com/animir/node-rate-limiter-flexible#benchmark).\n\n**Flexible.** Combine limiters, block key for some duration, delay actions, manage failover with insurance options, configure smart key blocking in memory and many others.\n\n**Ready for growth.** It provides a unified API for all limiters. Whenever your application grows, it is ready. Prepare your limiters in minutes.\n\n**Friendly.** No matter which node package you prefer: [`valkey-glide`](https://www.npmjs.com/package/@valkey/valkey-glide) or [`iovalkey`](https://www.npmjs.com/package/iovalkey), `redis` or `ioredis`, `sequelize`/`typeorm` or `knex`, `memcached`, native driver or `mongoose`. It works with all of them.\n\n**Safe for using with valkey cluster.** [`valkey-glide`](https://www.npmjs.com/package/@valkey/valkey-glide) implementation, [RateLimiterValkeyGlide](https://github.com/animir/node-rate-limiter-flexible/wiki/Valkey-Glide), is being tested to ensure compatibility and high performance.\n\n**In-memory blocks.** Avoid extra requests to store with [inMemoryBlockOnConsumed](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#inmemoryblockonconsumed).\n\nAllow **traffic bursts** with [BurstyRateLimiter](https://github.com/animir/node-rate-limiter-flexible/wiki/BurstyRateLimiter).\n\n**Deno compatible** See [this example](https://gist.github.com/animir/d06ca92931677f330d3f2d4c6c3108e4) \n\nIt uses a **fixed window**, as it is much faster than a rolling window. \n[See comparative benchmarks with other libraries here](https://github.com/animir/node-rate-limiter-flexible/wiki/Comparative-benchmarks)\n\n## Installation\n\n`npm i --save rate-limiter-flexible`\n\n`yarn add rate-limiter-flexible`\n\n## Import\n  \n  ```javascript\n  // CommonJS\n  const { RateLimiterMemory } = require(\"rate-limiter-flexible\");\n\n  // or\n\n  // ECMAScript \n  import { RateLimiterMemory } from \"rate-limiter-flexible\";\n  // or\n  import RateLimiterMemory from \"rate-limiter-flexible/lib/RateLimiterMemory.js\";\n  ```\n\n## Basic Example\n\nPoints can be consumed by IP address, user ID, authorisation token, API route or any other string.\n\n```javascript\nconst opts = {\n  points: 6, // 6 points\n  duration: 1, // Per second\n};\n\nconst rateLimiter = new RateLimiterMemory(opts);\n\nrateLimiter.consume(remoteAddress, 2) // consume 2 points\n    .then((rateLimiterRes) =\u003e {\n      // 2 points consumed\n    })\n    .catch((rateLimiterRes) =\u003e {\n      // Not enough points to consume\n    });\n```\n\n#### RateLimiterRes object\n\nThe Promise's `resolve` and `reject` callbacks both return an instance of the `RateLimiterRes` class if there is no error.\nObject attributes:\n```javascript\nRateLimiterRes = {\n    msBeforeNext: 250, // Number of milliseconds before next action can be done\n    remainingPoints: 0, // Number of remaining points in current duration \n    consumedPoints: 5, // Number of consumed points in current duration \n    isFirstInDuration: false, // action is first in current duration \n}\n```\n\nYou may want to set HTTP headers for the response:\n```javascript\nconst headers = {\n  \"Retry-After\": rateLimiterRes.msBeforeNext / 1000,\n  \"X-RateLimit-Limit\": opts.points,\n  \"X-RateLimit-Remaining\": rateLimiterRes.remainingPoints,\n  \"X-RateLimit-Reset\": Math.ceil((Date.now() + rateLimiterRes.msBeforeNext) / 1000)\n}\n```\n\n### Advantages:\n* no race conditions\n* no production dependencies\n* TypeScript declaration bundled\n* Block Strategy against really powerful DDoS attacks (like 100k requests per sec) [Read about it and benchmarking here](https://github.com/animir/node-rate-limiter-flexible/wiki/In-memory-Block-Strategy)\n* Insurance Strategy as emergency solution if database/store is down [Read about Insurance Strategy here](https://github.com/animir/node-rate-limiter-flexible/wiki/Insurance-Strategy)\n* works in Cluster or PM2 without additional software [See RateLimiterCluster benchmark and detailed description here](https://github.com/animir/node-rate-limiter-flexible/wiki/Cluster)\n* useful `get`, `set`, `block`, `delete`, `penalty` and `reward` methods\n\nFull documentation is on [Wiki](https://github.com/animir/node-rate-limiter-flexible/wiki)\n\n### Middlewares,  plugins and other packages\n* [Express middleware](https://github.com/animir/node-rate-limiter-flexible/wiki/Express-Middleware)\n* [Koa middleware](https://github.com/animir/node-rate-limiter-flexible/wiki/Koa-Middleware)\n* [Hapi plugin](https://github.com/animir/node-rate-limiter-flexible/wiki/Hapi-plugin)\n* GraphQL [graphql-rate-limit-directive](https://www.npmjs.com/package/graphql-rate-limit-directive)\n* NestJS try [nestjs-rate-limiter](https://www.npmjs.com/package/nestjs-rate-limiter)\n* Fastify based NestJS app try [nestjs-fastify-rate-limiter](https://www.npmjs.com/package/nestjs-fastify-rate-limiter)\n\nSome copy/paste examples on Wiki:\n* [Minimal protection against password brute-force](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#minimal-protection-against-password-brute-force)\n* [Login endpoint protection](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#login-endpoint-protection)\n* [Websocket connection prevent flooding](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#websocket-single-connection-prevent-flooding)\n* [Dynamic block duration](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#dynamic-block-duration)\n* [Authorized users specific limits](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#authorized-and-not-authorized-users)\n* [Different limits for different parts of application](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#different-limits-for-different-parts-of-application)\n* [Apply Block Strategy](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#apply-in-memory-block-strategy-to-avoid-extra-requests-to-store)\n* [Setup Insurance Strategy](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#setup-insurance-strategy-for-store-limiters)\n* [Third-party API, crawler, bot rate limiting](https://github.com/animir/node-rate-limiter-flexible/wiki/Overall-example#third-party-api-crawler-bot-rate-limiting)\n\n### Migration from other packages\n* [express-brute](https://github.com/animir/node-rate-limiter-flexible/wiki/ExpressBrute-migration) Bonus: race conditions fixed, prod deps removed\n* [limiter](https://github.com/animir/node-rate-limiter-flexible/wiki/RateLimiterQueue#migration-from-limiter) Bonus: multi-server support, respects queue order, native promises\n\n### Docs and Examples\n\n* [Options](https://github.com/animir/node-rate-limiter-flexible/wiki/Options)\n* [API methods](https://github.com/animir/node-rate-limiter-flexible/wiki/API-methods)\n* Valkey: [ValkeyGlide](https://github.com/animir/node-rate-limiter-flexible/wiki/Valkey-Glide) or [iovalkey](https://github.com/animir/node-rate-limiter-flexible/wiki/IoValkey)\n* [Redis](https://github.com/animir/node-rate-limiter-flexible/wiki/Redis)\n* [Memory](https://github.com/animir/node-rate-limiter-flexible/wiki/Memory)\n* [DynamoDb](https://github.com/animir/node-rate-limiter-flexible/wiki/DynamoDB)\n* [Etcd](https://github.com/animir/node-rate-limiter-flexible/wiki/Etcd)\n* [Prisma](https://github.com/animir/node-rate-limiter-flexible/wiki/Prisma)\n* [BurstyRateLimiter](https://github.com/animir/node-rate-limiter-flexible/wiki/BurstyRateLimiter) Traffic burst support\n* [Mongo](https://github.com/animir/node-rate-limiter-flexible/wiki/Mongo) (with [sharding support](https://github.com/animir/node-rate-limiter-flexible/wiki/Mongo#mongodb-sharding-options))\n* [MySQL](https://github.com/animir/node-rate-limiter-flexible/wiki/MySQL) (support Sequelize and Knex)\n* [Postgres](https://github.com/animir/node-rate-limiter-flexible/wiki/PostgreSQL) (support Sequelize, TypeORM and Knex)\n* [SQLite](https://github.com/animir/node-rate-limiter-flexible/wiki/SQLite)\n* [RateLimiterCluster](https://github.com/animir/node-rate-limiter-flexible/wiki/Cluster) ([PM2 cluster docs read here](https://github.com/animir/node-rate-limiter-flexible/wiki/PM2-cluster))\n* [Memcached](https://github.com/animir/node-rate-limiter-flexible/wiki/Memcache)\n* [RateLimiterUnion](https://github.com/animir/node-rate-limiter-flexible/wiki/RateLimiterUnion) Combine 2 or more limiters to act as single\n* [RLWrapperBlackAndWhite](https://github.com/animir/node-rate-limiter-flexible/wiki/Black-and-White-lists) Black and White lists\n* [RateLimiterQueue](https://github.com/animir/node-rate-limiter-flexible/wiki/RateLimiterQueue) Rate limiter with FIFO queue\n\n### Changelog\n\nSee [releases](https://github.com/animir/node-rate-limiter-flexible/releases) for detailed changelog.\n\n## Basic Options\n\n* **points** \n    \n    `Default: 4` \n    \n    Maximum number of points that can be consumed over duration\n\n* **duration** \n\n    `Default: 1` \n    \n    Number of seconds before consumed points are reset.\n    \n    Points are never reset if `duration` is set to 0.\n\n* **storeClient** \n\n    `Required for store limiters` \n\n    Must be `@valkey/valkey-glide`, `iovalkey`, `redis`, `ioredis`, `memcached`, `mongodb`, `pg`, `mysql2`, `mysql` or any other related pool or connection.\n\n### Other options on Wiki:\n* [keyPrefix](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#keyprefix) Make keys unique among different limiters.\n* [blockDuration](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#blockduration) Block for N seconds, if consumed more than points.\n* [inMemoryBlockOnConsumed](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#inmemoryblockonconsumed) Avoid extra requests to store.\n* [inMemoryBlockDuration](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#inmemoryblockduration)\n* [insuranceLimiter](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#insurancelimiter) Make it more stable with less efforts.\n* [storeType](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#storetype) Have to be set to `knex`, if you use it.\n* [dbName](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#dbname) Where to store points.\n* [tableName](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#tablename) Table/collection.\n* [tableCreated](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#tablecreated) Is table already created in MySQL, SQLite or PostgreSQL.\n* [clearExpiredByTimeout](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#clearexpiredbytimeout) For MySQL, SQLite and PostgreSQL.\n\nSmooth out traffic peaks:\n* [execEvenly](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#execevenly)\n* [execEvenlyMinDelayMs](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#execevenlymindelayms)\n\nSpecific:\n* [indexKeyPrefix](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#indexkeyprefix) Combined indexes of MongoDB.\n* [timeoutMs](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#timeoutms) For Cluster.\n* [rejectIfRedisNotReady](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#rejectifredisnotready)\n* [useRedisPackage](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#useredispackage)\n* [useRedis3AndLowerPackage](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#useredis3andlowerpackage)\n* [customIncrTtlLuaScript](https://github.com/animir/node-rate-limiter-flexible/wiki/Options#customincrttlluascript)\n\n## API\n\nRead detailed description on Wiki.\n\n* [consume(key, points = 1)](https://github.com/animir/node-rate-limiter-flexible/wiki/API-methods#ratelimiterconsumekey-points--1) Consume points by key.\n* [get(key)](https://github.com/animir/node-rate-limiter-flexible/wiki/API-methods#ratelimitergetkey) Get `RateLimiterRes` or `null`.\n* [set(key, points, secDuration)](https://github.com/animir/node-rate-limiter-flexible/wiki/API-methods#ratelimitersetkey-points-secduration) Set points by key.\n* [block(key, secDuration)](https://github.com/animir/node-rate-limiter-flexible/wiki/API-methods#ratelimiterblockkey-secduration) Block key for `secDuration` seconds.\n* [delete(key)](https://github.com/animir/node-rate-limiter-flexible/wiki/API-methods#ratelimiterdeletekey) Reset consumed points.\n* [deleteInMemoryBlockedAll](https://github.com/animir/node-rate-limiter-flexible/wiki/API-methods#ratelimiterdeleteinmemoryblockedall)\n* [penalty(key, points = 1)](https://github.com/animir/node-rate-limiter-flexible/wiki/API-methods#ratelimiterpenaltykey-points--1) Increase number of consumed points in current duration.\n* [reward(key, points = 1)](https://github.com/animir/node-rate-limiter-flexible/wiki/API-methods#ratelimiterrewardkey-points--1) Decrease number of consumed points in current duration.\n* [getKey(key)](https://github.com/animir/node-rate-limiter-flexible/wiki/API-methods#ratelimitergetkeykey) Get internal prefixed key.\n\n## Contributions\n\nAppreciated, feel free!\n\nMake sure you've launched `npm run eslint` before creating PR, all errors have to be fixed.\n\nYou can try to run `npm run eslint-fix` to fix some issues.\n\nAny new limiter with storage must be extended from `RateLimiterStoreAbstract`.\nIt has to implement 4 methods:\n* `_getRateLimiterRes` parses raw data from store to `RateLimiterRes` object.\n* `_upsert` may be atomic or non-atomic upsert (increment). It inserts or updates the value by key and returns raw data. \n    If it doesn't make an atomic upsert (increment), the class should be suffixed with `NonAtomic`, e.g. `RateLimiterRedisNonAtomic`. \n    \n    It must support `forceExpire` mode to overwrite key expiration time.\n* `_get` returns raw data by key or `null` if there is no key.\n* `_delete` deletes all key-related data and returns `true` on deleted, `false` if key is not found.\n\nAll other methods depends on the store. See `RateLimiterRedis` or `RateLimiterPostgres` for examples.\n\nNote: all changes should be covered by tests.\n","funding_links":["https://ko-fi.com/animir","https://patreon.com/animir"],"categories":["Packages","Repository","\u003ca id=\"73c3c9225523cbb05333246f23342846\"\u003e\u003c/a\u003e工具","\u003ca id=\"de81f9dd79c219c876c1313cd97852ce\"\u003e\u003c/a\u003e破解\u0026\u0026Crack\u0026\u0026爆破\u0026\u0026BruteForce","JavaScript","包","目录","express","sqlite","仓库"],"sub_categories":["Security","RateLimit","\u003ca id=\"53084c21ff85ffad3dd9ce445684978b\"\u003e\u003c/a\u003e未分类的","\u003ca id=\"f2c76d99a0b1fda124d210bd1bbc8f3f\"\u003e\u003c/a\u003eWordlist生成","安全","安全相关","中间件"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanimir%2Fnode-rate-limiter-flexible","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanimir%2Fnode-rate-limiter-flexible","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanimir%2Fnode-rate-limiter-flexible/lists"}