# @routup/rate-limit

> Routup rate limiter.

Latest version **4.0.0** (published 2026-05-20) · MIT license · 0 weekly downloads

## Install

```sh
npm install @routup/rate-limit
pnpm add @routup/rate-limit
yarn add @routup/rate-limit
bun add @routup/rate-limit
```

## Health

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

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

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 4.0.0 |
| Published | 2026-05-20 |
| First published | 2023-01-05 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM |
| Dependencies | 0 |
| Unpacked size | 36.2 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1 |
| Author | Peter Placzek |
| Maintainers | tada5hi |
| Keywords | rate, limit, request, rate-limit, rate-limiter |

## Links

- npm: https://www.npmjs.com/package/@routup/rate-limit
- Repository: https://github.com/routup/plugins
- Homepage: https://github.com/routup/plugins#readme
- Issues: https://github.com/routup/plugins/issues
- npm.io page: https://npm.io/package/@routup/rate-limit

## Alternatives

- [@commercetools/sync-actions](https://npm.io/package/@commercetools/sync-actions.md) — 25.1K weekly downloads
- [cwait](https://npm.io/package/cwait.md) — 21.4K weekly downloads
- [@ledgerhq/hw-app-cosmos](https://npm.io/package/@ledgerhq/hw-app-cosmos.md) — 4.2K weekly downloads
- [@financial-times/o-loading](https://npm.io/package/@financial-times/o-loading.md) — 2.8K weekly downloads
- [fa](https://npm.io/package/fa.md) — 185 weekly downloads

## Recent versions

- 4.0.0 (latest) — 2026-05-20
- 3.2.0 — 2026-05-12
- 3.1.0 — 2026-05-06
- 3.0.0 — 2026-05-05
- 2.4.2 — 2025-11-26
- 2.4.1 — 2025-06-25
- 2.4.0 — 2024-06-29
- 2.3.0 — 2023-11-21
- 2.2.0 — 2023-11-20
- 2.1.0 — 2023-10-22
- 2.0.0 — 2023-10-04
- 2.0.0-alpha.3 — 2023-10-04
- 2.0.0-alpha.0 — 2023-09-30
- 1.0.2 — 2023-09-14
- 1.0.1 — 2023-05-29
- … 12 more at https://npm.io/package/@routup/rate-limit/versions

## README

# @routup/rate-limit

[![npm version](https://badge.fury.io/js/@routup%2Frate-limit.svg)](https://badge.fury.io/js/@routup%2Frate-limit)
[![main](https://github.com/routup/plugins/actions/workflows/main.yml/badge.svg)](https://github.com/routup/plugins/actions/workflows/main.yml)
[![codecov](https://codecov.io/gh/routup/plugins/branch/master/graph/badge.svg)](https://codecov.io/gh/routup/plugins)
[![Known Vulnerabilities](https://snyk.io/test/github/routup/plugins/badge.svg)](https://snyk.io/test/github/routup/plugins)
[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits&logoColor=white)](https://conventionalcommits.org)

This is a rate-limiter middleware.

**Table of Contents**

- [Installation](#installation)
- [Documentation](#documentation)
- [Usage](#usage)
  - [Store](#store)
- [Options](#options)
  - [windowsMs](#windowms)
  - [max](#max)
  - [message](#message)
  - [statusCode](#statuscode)
  - [skipFailedRequest](#skipfailedrequest)
  - [skipSuccessFulRequest](#skipsuccessfulrequest)
  - [keyGenerator](#keygenerator)
  - [handler](#handler)
  - [skip](#skip)
  - [requestWasSuccessful](#requestwassuccessful)
  - [store](#store)
- [License](#license)

## Installation

```bash
npm install @routup/rate-limit --save
```

## Documentation

To read the docs, visit [https://routup.net](https://routup.net)

## Usage

```typescript
import {
    App,
    serve,
} from 'routup';
import { rateLimit } from '@routup/rate-limit';

const router = new App();

router.use(rateLimit({
    // 15 minutes
    windowMs: 15 * 60 * 1000,

    // Limit each IP to 100 requests
    // per `window` (here, per 15 minutes)
    max: 100,
}));

serve(router, { port: 3000 });
```

### Store

To create a custom Store it is mandatory to extend the `Store` interface.
The following adapters are officially provided:
- [@routup/rate-limit-redis](https://www.npmjs.com/package/@routup/rate-limit-redis)

## Options

### `windowMs`

> `number`

Time frame for which requests are checked/remembered. Also used in the
`Retry-After` header when the limit is reached.

Defaults to `60000` ms (= 1 minute).

### `max`

> `number | function`

The maximum number of connections to allow during the `window` before rate
limiting the client.

Can be the limit itself as a number or a (sync/async) function that accepts the
routup `event` and then returns a number.

Defaults to `5`. Set it to `0` to disable the rate limiter.

An example of using a function:

```ts
const isPremium = async (ip: string) => {
	// ...
}

const handler = createHandler({
    // ...
    max: async (event) => {
        const ip = getRequestIP(event, { trustProxy: true }) || '127.0.0.1';
        if (await isPremium(ip)) return 10
        else return 5
    },
})
```

### `message`

> `any`

The response body to send back when a client is rate limited.

May be a `string`, JSON object, or any other value.
It can also be a (sync/async) function that accepts the routup `event`
and then returns a `string`, JSON object or any other value.

Defaults to `'Too many requests, please try again later.'`

An example of using a function:

```ts
const isPremium = async (ip: string) => {
	// ...
}

const handler = createHandler({
    // ...
    message: async (event) => {
        const ip = getRequestIP(event, { trustProxy: true }) || '127.0.0.1';
        if (await isPremium(ip)) {
            return 'You can only make 10 requests every hour.'
        }
			
        return 'You can only make 5 requests every hour.'
    },
})
```

### `statusCode`

> `number`

The HTTP status code to send back when a client is rate limited.

Defaults to `429` (HTTP 429 Too Many Requests - RFC 6585).

### `skipFailedRequest`

> `boolean`

When set to `true`, failed requests won't be counted. Request considered failed
when the `requestWasSuccessful` option returns `false`. By default, this means
requests fail when the response status >= 400.

Defaults to `false`.

### `skipSuccessfulRequest`

> `boolean`

If `true`, the library will (by default) skip all requests that are considered
'successful' by the `requestWasSuccessful` function. By default, this means requests
succeed when the response status code < 400.

Defaults to `false`.

### `keyGenerator`

> `function`

Method to generate custom identifiers for clients.

Should be a (sync/async) function that accepts the routup `event`
and then returns a string.

By default, the client's IP address is used:

```ts
import { getRequestIP } from 'routup';

const handler = createHandler({
    // ...
    keyGenerator: (event) => getRequestIP(event, { trustProxy: true }),
})
```

### `handler`

> `function`

Handler that sends back a response when a client is rate-limited.

By default, sends back the `statusCode` and `message` set via the `options`,
similar to this:

```ts
const handler = createHandler({
    // ...
    handler(event, options) {
        event.response.status = options.statusCode;
        return options.message;
    }
})
```

### `skip`

> `function`

Function to determine whether this request counts towards a client's
quota. Should be a (sync/async) function that accepts the routup `event`
and then returns `true` or `false`.

Could also act as an allow list for certain keys:

```ts
const allowlist = ['192.168.0.56', '192.168.0.21']

const handler = createHandler({
    // ...
    skip: (event) => allowlist.includes(getRequestIP(event)),
})
```

By default, it skips no requests:

```ts
const handler = createHandler({
    // ...
    skip: (event) => false,
})
```

### `requestWasSuccessful`

> `function`

Method to determine whether the request counts as 'successful'. Used when
either `skipSuccessfulRequest` or `skipFailedRequest` is set to true. Should
be a function that accepts the routup `event` and the downstream `Response`
object and then returns `true` or `false`.

By default, requests with a response status code less than 400 are considered
successful:

```ts
const handler = createHandler({
    // ...
    requestWasSuccessful: (event, response) => response.status < 400,
})
```

### `store`

The `Store` to use to store the hit count for each client.

## License

Made with 💚

Published under [MIT License](./LICENSE).

This library is heavily inspired by
[express-rate-limit](https://www.npmjs.com/package/express-rate-limit).

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