No configuration is required, all options have reasonable defaults.

Any option that may be set to a function may also be set to an async function, or to a function that returns a promise. Async functions and promises will be awaited for the value.

windowMs

number

Time frame for which requests are checked/remembered. The time window for each user starts at their first request. After it elapses, the user’s hit count is reset to zero. A new time window is then started on their next request.

Also used in the Retry-After header when the limit is reached.

This value cannot be set to a function. If multiple time windows are needed, create multiple rate limiters.

For stores that do not implement the init function (including all legacy stores - see the data stores page), you may need to configure this value twice, once here and once on the store. In some cases the units also differ (e.g. seconds vs milliseconds).

Defaults to 60000 ms (= 1 minute).

limit

number | function

Renamed in v7.x from max to limit. However, max will still be supported for backwards-compatibility.

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 Express req and res objects and then returns a number.

As of version 7.0.0, setting max to zero will no longer disable the rate limiter - instead, it will ‘block’ all requests to that endpoint.

Defaults to 5.

An example of using a function:

const isPremium = async (user) => {
	// ...
}

const limiter = rateLimit({
	// ...
	limit: async (req, res) => {
		if (await isPremium(req.user)) 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 that Express’s res.send method supports. It can also be a (sync/async) function that accepts the Express request and response objects and then returns a string, JSON object, etc.

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

An example of using a function:

const isPremium = async (user) => {
	// ...
}

const limiter = rateLimit({
	// ...
	message: async (req, res) => {
		if (await isPremium(req.user))
			return 'You can only make 10 requests every hour.'
		else return 'You can only make 5 requests every hour.'
	},
})

Set a custom handler for more advanced use-cases, such as using res.render() to send a templated response.

statusCode

number

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

Defaults to 429.

The HTTP status code 429 is defined in section 4 of IETF’s RFC 6585.

handler

function

Express request 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:

const limiter = rateLimit({
	// ...
	handler: (req, res, next, options) =>
		res.status(options.statusCode).send(options.message),
})

legacyHeaders

boolean

Renamed in 6.x from headers to legacyHeaders.

Whether to send the legacy rate limit headers for the limit (X-RateLimit-Limit), current usage (X-RateLimit-Remaining) and reset time (if the store provides it) (X-RateLimit-Reset) on all responses. If set to true, the middleware also sends the Retry-After header on all blocked requests.

Defaults to true.

Note that this option only defaults to true for backward compatibility, and it is recommended to set it to false and use standardHeaders instead.

standardHeaders

boolean | 'draft-6' | 'draft-7'

Renamed in 6.x from draft_polli_ratelimit_headers to standardHeaders.

Whether to enable support for headers conforming to the RateLimit header fields for HTTP standardization draft adopted by the IETF.

If set to draft-6, separate RateLimit-Policy RateLimit-Limit, RateLimit-Remaining, and, if the store supports it, RateLimit-Reset headers are set on the response, in accordance with the sixth draft of the IETF rate limit header specification.

If set to draft-7, a combined RateLimit header is set containing limit, remaining, and reset values, and a RateLimit-Policy header is set, in accordiance with the seventh draft of the IETF rate limit header specification. windowMs is used for the reset value if the store does not provide a reset time.

If set to true, it is treated as draft-6, however, this behavior may change in a future semver major release.

If set to any truthy value, the middleware also sends the Retry-After header on all blocked requests.

The standardHeaders option may be used in conjunction with, or instead of the legacyHeaders option.

Tip: use the ratelimit-header-parser library in clients to read/parse any form of headers.

Defaults to false.

store

Store

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

By default, the memory-store is used.

See Data Stores for a list of avalliable stores and other information.

keyGenerator

function

Method to retrieve custom identifiers for clients, such as their IP address, username, or API Key.

Should be a (sync/async) function that accepts the Express request and response objects and then returns a string.

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

const limiter = rateLimit({
	// ...
	keyGenerator: (req, res) => req.ip,
})

If a keyGenerator returns the same value for every user, it becomes a global rate limiter. This could be combined with a second instance of express-rate-limit to have both global and per-user limits.

requestPropertyName

string

The name of the property on the Express request object to store the rate limit info.

Defaults to 'rateLimit'.

skip

function

Function to determine whether or not this request counts towards a client’s quota. Should be a (sync/async) function that accepts the Express request and response objects and then returns true or false.

Could also act as an allowlist for certain keys:

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

const limiter = rateLimit({
	// ...
	skip: (req, res) => allowlist.includes(req.ip),
})

By default, it skips no requests:

const limiter = rateLimit({
	// ...
	skip: (req, res) => false,
})

skipSuccessfulRequests

boolean

If true, the library will (by default) skip all requests that are considered ‘failed’ by the requestWasSuccessful function. By default, this means requests succeed when the response status code less than 400.

Technically, the requests are counted and then un-counted, so a large number of slow requests all at once could still trigger a rate-limit. This may be fixed in a future release. PRs welcome!

Defaults to false.

skipFailedRequests

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
  • the request was cancelled before last chunk of data was sent (response close event triggered)
  • the response error event was triggered by response

Technically, the requests are counted and then un-counted, so a large number of slow requests all at once could still trigger a rate-limit. This may be fixed in a future release. PRs welcome!

Defaults to false.

requestWasSuccessful

function

Method to determine whether or not the request counts as ‘successful’. Used when either skipSuccessfulRequests or skipFailedRequests is set to true. Should be a (sync/async) function that accepts the Express req and res objects and then returns true or false.

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

const limiter = rateLimit({
	// ...
	requestWasSuccessful: (req, res) => res.statusCode < 400,
})

validate

boolean | Object

When enabled, a set of validation checks are run at creation and on the first request to detect common misconfigurations with proxies, etc. Prints an error to the console if any issue is detected.

Automatically disables after the first request is processed.

If set to true or false, all validations are enabled or disabled.

If set to an object, individual validations can be enabled or disabled by name, and the key default controls all unspecified validations. For example:

const limiter = rateLimit({
	validate: {
		xForwardedForHeader: false,
		default: true,
	},
	// ...
})

Supported validations are:

Defaults to true.