# express-rate-limit

> Basic IP rate-limiting middleware for Express. Use to limit repeated requests to public APIs and/or endpoints such as password reset.

Latest version **8.7.0** (published 2026-08-29) · MIT license · 0 weekly downloads

## Install

```sh
npm install express-rate-limit
pnpm add express-rate-limit
yarn add express-rate-limit
bun add express-rate-limit
```

## Health

**Score 75/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; has provenance; recently updated; high maintenance score; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 8.7.0 |
| Published | 2026-08-29 |
| First published | 2014-12-11 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >= 16 |
| Dependencies | 2 |
| Unpacked size | 151 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 3306 |
| Author | Nathan Friedly |
| Maintainers | nfriedly, gamemaker1 |
| Keywords | express-rate-limit, express, rate, limit, ratelimit, rate-limit, middleware, ip, auth, authorization, security, brute, force, bruteforce, brute-force, attack |

## Links

- npm: https://www.npmjs.com/package/express-rate-limit
- Repository: https://github.com/express-rate-limit/express-rate-limit
- Issues: https://github.com/express-rate-limit/express-rate-limit/issues
- Funding: https://github.com/sponsors/express-rate-limit
- npm.io page: https://npm.io/package/express-rate-limit

## Dependencies (2)

- [debug](https://npm.io/package/debug.md) ^4.4.3
- [ip-address](https://npm.io/package/ip-address.md) ^10.2.0

## Alternatives

- [@clerk/clerk-expo](https://npm.io/package/@clerk/clerk-expo.md) — 133.6K weekly downloads
- [@pothos/plugin-authz](https://npm.io/package/@pothos/plugin-authz.md) — 12.4K weekly downloads
- [@bounded-sh/client](https://npm.io/package/@bounded-sh/client.md) — 3.2K weekly downloads
- [@luigi-project/plugin-auth-oauth2](https://npm.io/package/@luigi-project/plugin-auth-oauth2.md) — 2.3K weekly downloads
- [@nocobase/plugin-verification](https://npm.io/package/@nocobase/plugin-verification.md) — 2.0K weekly downloads

## Recent versions

- 8.7.0 (latest) — 2026-08-29
- 8.0.2 (backport-8.0.x) — 2026-03-05
- 8.2.2 (backport-8.2.x) — 2026-03-05
- 8.1.1 (backport-8.1.x) — 2026-03-05
- 0.0.0-typescript-beta-7 (typescript) — 2019-07-12
- 3.5.3 (backport-3.x) — 2019-05-22
- 2.14.2 (v2backports) — 2018-08-23
- 8.6.2 — 2026-08-04
- 8.6.1 — 2026-07-26
- 8.6.0 — 2026-07-16
- 8.5.2 — 2026-05-14
- 8.5.1 — 2026-05-06
- 8.5.0 — 2026-05-04
- 8.4.1 — 2026-04-24
- 8.4.0 — 2026-04-23
- … 115 more at https://npm.io/package/express-rate-limit/versions

## README

<h1 align="center"> <code>express-rate-limit</code> </h1>

<div align="center">

[![tests](https://img.shields.io/github/actions/workflow/status/express-rate-limit/express-rate-limit/ci.yaml)](https://github.com/express-rate-limit/express-rate-limit/actions/workflows/ci.yaml)
[![npm version](https://img.shields.io/npm/v/express-rate-limit.svg)](https://npmjs.org/package/express-rate-limit 'View this project on NPM')
[![npm downloads](https://img.shields.io/npm/dm/express-rate-limit)](https://www.npmjs.com/package/express-rate-limit)
[![inspect.software](https://raw.githubusercontent.com/inspect-software/badges/main/v1/e/express-rate-limit/express-rate-limit.svg)](https://inspect.software/software/express-rate-limit/express-rate-limit)
[![license](https://img.shields.io/npm/l/express-rate-limit)](license.md)

</div>

Basic rate-limiting middleware for [Express](http://expressjs.com/). Use to
limit repeated requests to public APIs and/or endpoints such as password reset.
Plays nice with
[express-slow-down](https://www.npmjs.com/package/express-slow-down) and
[ratelimit-header-parser](https://www.npmjs.com/package/ratelimit-header-parser).

## Usage

The [full documentation](https://express-rate-limit.mintlify.app/overview) is
available on-line.

```ts
import { rateLimit } from 'express-rate-limit'

const limiter = rateLimit({
	windowMs: 15 * 60 * 1000, // 15 minutes
	limit: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes).
	standardHeaders: 'draft-8', // draft-6: `RateLimit-*` headers; draft-7 & draft-8: combined `RateLimit` header
	legacyHeaders: false, // Disable the `X-RateLimit-*` headers.
	ipv6Subnet: 56, // Set to 60 or 64 to be less aggressive, or 52 or 48 to be more aggressive
	// store: ... , // Redis, Memcached, etc. See below.
})

// Apply the rate limiting middleware to all requests.
app.use(limiter)
```

### Data Stores

The rate limiter comes with a built-in memory store, and supports a variety of
[external data stores](https://express-rate-limit.mintlify.app/reference/stores).

### Configuration

All function options may be async. Click the name for additional info and
default values.

| Option                     | Type                                      | Remarks                                                                                         |
| -------------------------- | ----------------------------------------- | ----------------------------------------------------------------------------------------------- |
| [`windowMs`]               | `number`                                  | How long to remember requests for, in milliseconds.                                             |
| [`limit`]                  | `number` \| `function`                    | How many requests to allow.                                                                     |
| [`message`]                | `string` \| `json` \| `function`          | Response to return after limit is reached.                                                      |
| [`statusCode`]             | `number`                                  | HTTP status code after limit is reached (default is 429).                                       |
| [`handler`]                | `function`                                | Function to run after limit is reached (overrides `message` and `statusCode` settings, if set). |
| [`legacyHeaders`]          | `boolean`                                 | Enable the `X-Rate-Limit` header.                                                               |
| [`standardHeaders`]        | `'draft-6'` \| `'draft-7'` \| `'draft-8'` | Enable the `Ratelimit` header.                                                                  |
| [`identifier`]             | `string` \| `function`                    | Name associated with the quota policy enforced by this rate limiter.                            |
| [`store`]                  | `Store`                                   | Use a custom store to share hit counts across multiple nodes.                                   |
| [`passOnStoreError`]       | `boolean`                                 | Allow (`true`) or block (`false`, default) traffic if the store becomes unavailable.            |
| [`keyGenerator`]           | `function`                                | Identify users (defaults to IP address).                                                        |
| [`ipv6Subnet`]             | `number` (32-64) \| `function` \| `false` | How many bits of IPv6 addresses to use in default `keyGenerator`                                |
| [`requestPropertyName`]    | `string`                                  | Add rate limit info to the `req` object.                                                        |
| [`skip`]                   | `function`                                | Return `true` to bypass the limiter for the given request.                                      |
| [`skipSuccessfulRequests`] | `boolean`                                 | Uncount 1xx/2xx/3xx responses.                                                                  |
| [`skipFailedRequests`]     | `boolean`                                 | Uncount 4xx/5xx responses.                                                                      |
| [`requestWasSuccessful`]   | `function`                                | Used by `skipSuccessfulRequests` and `skipFailedRequests`.                                      |
| [`validate`]               | `boolean` \| `object`                     | Enable or disable built-in validation checks.                                                   |
| [`logger`]                 | `Logger`                                  | Custom logger                                                                                   |

## Thank You

---

Thanks to Mintlify for hosting the documentation at
[express-rate-limit.mintlify.app](https://express-rate-limit.mintlify.app)

<p align="center">
	<a href="https://mintlify.com/?utm_campaign=devmark&utm_medium=readme&utm_source=express-rate-limit">
		<img height="75" src="https://devmark-public-assets.s3.us-west-2.amazonaws.com/sponsorships/mintlify.svg" alt="Create your docs today">
	</a>
</p>

---

And thank you to everyone who's contributed to this project in any way! 🫶

## Issues and Contributing

If you encounter a bug or want to see something added/changed, please go ahead
and
[open an issue](https://github.com/express-rate-limit/express-rate-limit/issues/new)!
If you need help with something, feel free to
[start a discussion](https://github.com/express-rate-limit/express-rate-limit/discussions/new)!

If you wish to contribute to the library, thanks! First, please read
[the contributing guide](https://express-rate-limit.mintlify.app/guides/contributing).
Then you can pick up any issue and fix/implement it!

## License

MIT © [Nathan Friedly](http://nfriedly.com/),
[Vedant K](https://github.com/gamemaker1)

[`windowMs`]:
	https://express-rate-limit.mintlify.app/reference/configuration#windowms
[`limit`]: https://express-rate-limit.mintlify.app/reference/configuration#limit
[`message`]:
	https://express-rate-limit.mintlify.app/reference/configuration#message
[`statusCode`]:
	https://express-rate-limit.mintlify.app/reference/configuration#statuscode
[`handler`]:
	https://express-rate-limit.mintlify.app/reference/configuration#handler
[`legacyHeaders`]:
	https://express-rate-limit.mintlify.app/reference/configuration#legacyheaders
[`standardHeaders`]:
	https://express-rate-limit.mintlify.app/reference/configuration#standardheaders
[`identifier`]:
	https://express-rate-limit.mintlify.app/reference/configuration#identifier
[`store`]: https://express-rate-limit.mintlify.app/reference/configuration#store
[`passOnStoreError`]:
	https://express-rate-limit.mintlify.app/reference/configuration#passonstoreerror
[`keyGenerator`]:
	https://express-rate-limit.mintlify.app/reference/configuration#keygenerator
[`ipv6Subnet`]:
	https://express-rate-limit.mintlify.app/reference/configuration#ipv6subnet
[`requestPropertyName`]:
	https://express-rate-limit.mintlify.app/reference/configuration#requestpropertyname
[`skip`]: https://express-rate-limit.mintlify.app/reference/configuration#skip
[`skipSuccessfulRequests`]:
	https://express-rate-limit.mintlify.app/reference/configuration#skipsuccessfulrequests
[`skipFailedRequests`]:
	https://express-rate-limit.mintlify.app/reference/configuration#skipfailedrequests
[`requestWasSuccessful`]:
	https://express-rate-limit.mintlify.app/reference/configuration#requestwassuccessful
[`validate`]:
	https://express-rate-limit.mintlify.app/reference/configuration#validate
[`logger`]:
	https://express-rate-limit.mintlify.app/reference/configuration#logger

---
_Source: https://npm.io/package/express-rate-limit · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
