NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #1033 most downloaded on npm
Basic IP rate-limiting middleware for Express. Use to limit repeated requests to public APIs and/or endpoints such as password reset.
Last release 1 months ago
29 Aug 2026
Release timing varies
gaps range from 8 days to 4 months
Nearly every release is documented
notes for 57 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
12 years old
130 releases · first in 2014
You can view the changelog here .
You can view the changelog here.
Added
You can view the changelog here .
You can view the changelog here.
One column per quarter.
Fixed
You can view the changelog here .
You can view the changelog here.
Changed
You can view the changelog here .
You can view the changelog here.
Fixed
Added
Added DAY , HOUR , MINUTE , and SECOND constants for use with the windowMs setting.
Added support for debug logging - see https://express-rate-limit.mintlify.app/guides/debugging
Validations are now run once each instead of only during the first request.
This enables the IPv6 checks to run even if the first request happens to be IPv4.
It also prevents duplicate messages if the server receives multiple requests in parallel.
You can view the changelog here .
You can view the changelog here.
Fixed
You can view the changelog here .
You can view the changelog here.
Fixed
You can view the changelog here .
You can view the changelog here.
Added
You can view the changelog here .
You can view the changelog here.
Added
You can view the changelog here .
You can view the changelog here.
Added
You can view the changelog here .
You can view the changelog here.
Fixed
You can view the changelog here .
You can view the changelog here.
Fixed
Fixed npm provenance on automated releases
Fixed a broken link in the readme
You can view the changelog here.
You can view the changelog here.
Backported to previous minor versions as 8.2.2 , 8.1.1 , and 8.0.2 .
Security
Provenance note Due to an issue with automated publishing to npm, we opted to manually publish v8.3.0 in order to get the fix out quicker. Accitionally, our CI is not configured to handle backports, so we also manually released those.
Nothing published for this version
You can view the changelog here.
You can view the changelog here.
Fixed
You can view the changelog here.
You can view the changelog here.
Added
Nothing published for this version
You can view the changelog here.
You can view the changelog here.
Fixed
Added
New windowMs validation check that ensures it’s in the valid range when using the built-in Memory store.
New forwardedHeader validation check to warn when the Forwarded header is present but ignored.
Nothing published for this version
You can view the changelog here.
You can view the changelog here.
Fixed
ipKeyGenerator function is now correctly exported in CommonJS build
express’s Request and Response types are once again correctly referenced in .d.ts files
Changed
You can view the changelog here.
You can view the changelog here.
Breaking
IPv6 addresses are now masked with a /56 subnet by default. For example, the following two IP addresses will now be considered to be the same user and grouped together for rate-limiting:
0123:4567:89ab:cd11:1111:1111:1111:1111
0123:4567:89ab:cd22:2222:2222:2222:2222 (both would be normalized to 123:4567:89ab:cd00::/56 )
Fixed
Added
IPv6 addresses are now masked with a /56 subnet by default. For example, the following two IP addresses will now be considered to be the same user and grouped together for rate-limiting:
0123:4567:89ab:cd11:1111:1111:1111:11110123:4567:89ab:cd22:2222:2222:2222:2222(both would be normalized to 123:4567:89ab:cd00::/56)
ipv6Subnet configuration option used by the default keyGenerator, defaults
to 56ipKeyGenerator(ip, ipv6Subnet) helper method to apply the desired subnet to
IPv6 addresses (returns IPv4 unchanged)ipv6Subnet validation check on above configuration option's value (allowed
range is 32-64)ipv6SubnetOrKeyGenerator validation check to warn of an incompatible
combination of ipv6Subnet and keyGenerator settings.keyGeneratorIpFallback validation check on custom keyGenerators to ensure
they're using ipKeyGenerator if they reference req.ip or request.ipNarrowed type of standardHeaders from string to just the supported values via a TypeScript `const` assertion
standardHeaders from string to just the supported values via a TypeScript const assertion (#506)You can view the full changelog here.
Implemented the combined RateLimit header according to the eighth draft of the IETF RateLimit header specificiation. Enable by setting standardHeaders
RateLimit header according to the eighth draft of the IETF RateLimit header specificiation. Enable by setting standardHeaders: 'draft-8'.identifier option, used as the name for the quota policy in the draft-8 headers.headersDraftVersion validation check to identifies cases where an unsupported version string is passed to the standardHeaders option.You can view the full changelog here.
Made the passOnStoreError return after calling next() rather than continuing execution.
passOnStoreError return after calling next() rather than continuing execution.You can view the full changelog here.
Added passOnStoreError option to allow a way to "fail open" in the event of a backend error.
passOnStoreError option to allow a way to "fail open" in the event of a backend error.You can view the full changelog here.
Changed error displayed for the creationStack validation check when a store with localKeys set to false is used.
creationStack validation check when a store
with localKeys set to false is used.creationStack check.You can view the full changelog here.
Added a new unsharedStore validation check that identifies cases where a single store instance is shared across multiple limiters.
unsharedStore validation check that identifies cases where a
single store instance is shared across multiple limiters.You can view the full changelog here.
Added a new creationStack validation check that looks for instances created in a request handler.
creationStack validation check that looks for instances created
in a request handler.You can view the full changelog here.
Enable async requestWasSuccessful methods to work as documented.
async requestWasSuccessful methods to work as documented.You can view the full changelog here.
Ensure header values are strings rather than numbers, for compatibility with Bun.
Loosened peer dependencies to explicitly allow the Express 5 beta. (See #415)
Re-organized documentation from readme into docs/ folder and added documentation website.
You can view the full changelog here.
Enabled provenance statement generation, see https://github.com/express-rate-limit/express-rate-limit#406.
You can view the full changelog here.
Added
The getKey method is now always defined. If the store does not have the required get method, getKey will throw an error explaining this.
getKey method is now always defined. If the store does not have the
required get method, getKey will throw an error explaining this.You can view the full changelog here.
Added cluster-memory-store to the readme and made a couple of other minor clarifications.
cluster-memory-store to the readme and made a couple of other minor
clarifications.You can view the full changelog here.
Added rate-limit-postgresql to the stores list in the readme.
rate-limit-postgresql to the stores list in the readme.You can view the full changelog here.
Removed the draft_polli_ratelimit_headers option (it was deprecated in v6).
max is set to 0:
max: 0 was treated as a 'disable' flag and would allow all requests through.req.rateLimit.current to req.rateLimit.used.
current is now a hidden getter that will return the used value, but it will not appear when iterating over the keys or calling JSON.stringify().express-rate-limit now targets es2022 in TypeScript/ESBuild.dts-bundle-generator from v7 to v8.draft_polli_ratelimit_headers option (it was deprecated in v6).
standardHeaders: 'draft-6' instead.onLimitReached option (it was deprecated in v6).
handler option.MemoryStore now uses precise, per-user reset times rather than a global window that resets all users at once.limit configuration option is now prefered to max.
max is still supported. The change was made to better align with terminology used in the IETF standard drafts.validate config option can now be an object with keys to enable or disable specific validation checks. For more information, see this.Restored IncrementResponse TypeScript type (See #397)
IncrementResponse TypeScript type (See #397)Check for prefixed keys when validating that the stores have single counted keys (See #395).
Support for retrieving the current hit count and reset time for a given key from a store (See #390).
Warning when using deprecated draft_polli_ratelimit_headers option
RateLimit header from the RateLimit header fields for HTTP standardization draft adopted by the IETF. Enable by setting standardHeaders: 'draft-7'standardHeaders: 'draft-6' option, treated equivalent to standardHeaders: true from previous releases. (true and false are still supported.)RateLimit-Policy header added when standardHeaders is set to 'draft-6', 'draft-7', or truedraft_polli_ratelimit_headers optiononLimitReached optiontotalHits value returned from Store is invalidNew validaion check for double-counted requests
ValidationError, directing users to the appropriate wiki page for more infoYou can view the full changelog here.
Added
New validaion check for double-counted requests.
Added help link to each validation error, directing users to the appropriate wiki page for more info.
Changed
6.8.1 & 6.7.2
Changed
Revert 6.7.1 change that bumped typescript from 5.x to 4.x and dts-bundle-generator from 8.x to 7.x (See #360)
Added a set of validation checks that will log an error if failed. See https://github.com/express-rate-limit/express-rate-limit/wiki/Error-Codes for a
validate: false in
the configuration. Automatically disables after the first request. (See
#358)You can view the changelog here.
You can view the full changelog here.
(Backport of v6.8.1)
You can view the full changelog here.
Fixed compatibility with TypeScript's TypeScript new node16 module resolution strategy (See #355)
Fixed
Changed
Bumped development dependencies
This initially include bumping typescript from 4.x to 5.x and dts-bundle-generator from 7.x to 8.x
Added node 20 to list of versions the CI jobs run on. No functional changes.
Updated links to point to the new express-rate-limit organization on GitHub.
No functional changes.
express-rate-limit organization on GitHub.readme.md for project sponsor Zuplo.typescript version 5 and bumped other dependencies.node 12, and added node 19 to the list of versions the CI jobs run on.You can view the changelog here.
Added shutdown method to the Store interface and the MemoryStore.
shutdown method to the Store interface and the MemoryStore. (#322)You can view the full changelog here.
Fixed an issue with missing types in ESM monorepos.
The message option can now be a (sync/asynx) function that returns a value
Added
Changed
Adds Express 5 (5.0.0-beta.1) as a supported peer dependency
5.0.0-beta.1) as a supported peer dependency (#304)Changes the build target to es2019 so that ESBuild outputs code that can run with Node 12.
es2019 so that ESBuild outputs code that can run with Node 12.Use the default value for an option when undefined is passed to the rate limiter.
undefined is passed to the rate
limiter.Deprecate the onLimitReached option (this was supposed to be deprecated in v6.0.0 itself); developers should use a custom handler function that checks…
MemoryStore, so it can now be imported as a named import
(import { MemoryStore } from 'express-rate-limit').onLimitReached option (this was supposed to be deprecated in
v6.0.0 itself); developers should use a custom handler function that checks if
the rate limit has been exceeded instead.Added a named export rateLimit in case the default import does not work.
rateLimit in case the default import does not work.default, so Typescript CommonJS developers can default-import the library (import rateLimit from 'express-rate-limit').Use named imports for ExpressJS types so users do not need to enable the esModuleInterop flag in their Typescript compiler configuration.
esModuleInterop flag in their Typescript compiler configuration.Upload the built package as a .tgz to GitHub releases.
.tgz to GitHub releases. main and module fields to package.json. This helps tools such as ESLint that do not yet support the exports field.package-lock.json to match package.jsonBumped minimum Node version from 12.9 to 14.5 because the transpiled output uses the nullish coalescing operator (??), which isn't supported in Node p
??), which isn't supported in Node prior to 14.x.
Changed
Ensure CommonJS projects can import the module.
js-cjs, js-esm, ts-cjs, ts-esm environments.redis, mongo, memcached, precise).esbuild to generate ESM and CJS output. This reduces the size of the built package from 138 kb to 13kb and build time to 4 ms! :rocket:dts-bundle-generator to generate a single Typescript declaration file.Ensure CommonJS projects can import the module.
The onLimitReached configuration option is now deprecated. Replace it with a custom handler that checks the number of hits.
express 4.x as a peer dependency..tgz file) on GitHub releases as well as the npm registry.draft_polli_ratelimit_headers option to standardHeaders.headers option to legacyHeaders.Retry-After header is now sent if either legacyHeaders or standardHeaders is set.keyGenerator to be an async function/return a promise.init method for stores to set themselves up using options passed to the middleware.incr method to increment.increment, decrement, resetKey and resetAll methods to return a promise.onLimitReached configuration option is now deprecated. Replace it with a custom handler that checks the number of hits.limiter.resetIp method (use the limiter.resetKey method instead).delayMs, delayAfter (the delay functionality was moved to the express-slow-down package) and global (use a key generator that returns a constant value).Your coding agent can read these notes before it upgrades. Set up the MCP server →