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 sending a JSON object:
app.use(
	rateLimit({
		message: { error: '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' | 'draft-8' 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 accordance 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 draft-8, a combined RateLimit header is set containing the remaining and reset values, along with a RateLimit-Policy header, is set for each rate limiter defined, in accordance with the eighth draft of the IETF rate limit header specification. The value of windowMs is used for the reset parameter if the store does not provide a reset time. Note that the ninth draft of the IETF rate limit header specification does not specify any changes in the function or format of the headers. Set this option to draft-8 for the same.
If set to generate draft-7 or draft-8 headers, make sure that you are using Express v4.11 or later, as the implementation of these two drafts requires the response.append function.
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.

identifier

string | function
The name associated with the quota policy that this instance of the rate limiter enforces. It is used in the RateLimit and RateLimit-Policy headers when standardHeaders is set to draft-8, and ignored otherwise. Can be the identifier itself as a string or a (sync/async) function that accepts the Express req and res objects and then returns a string. Defaults to a function that returns a string of the format {limit}-in-{window}, e.g., 7-in-1.5sec.

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.

passOnStoreError

By default, this is false and express-rate-limit will call the express error handler in the event of a store error. In other words, the default is to “fail closed” and block all requests if the datastore becomes unavailable. Set this to true to “fail open” allow the request(s) through without rate limiting. The error will be logged in this case.

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 with the ipKeyGenerator method to apply the configured ipv6Subnet to IPv6 addresses. Custom keyGenerators that fall back to IP addresses should use the provided ipKeyGenerator method and a chosen subnet for IPv6 addresses (see ipv6Subnet discussion below.)
import { rateLimit, ipKeyGenerator } from 'express-rate-limit'
const limiter = rateLimit({
	// ...
	keyGenerator: (req, res) => ipKeyGenerator(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.

ipv6Subnet

number (32-64) | function | false
IPv6 subnet mask applied to IPv6 addresses in the default keyGenerator. Generally, ISPs that support IPv6 give each of their customers a range of IPv6 addresses via a subnet mask, whereas they usually provide only a single IPv4 address per customer. A malicious user could iterate through their range of IPv6 addresses and bypass simple IP-based rate limiting. This setting counteracts that by allowing the rate-limiter to block an entire range of IPv6 addresses at once. It’s generally not possible to know what subnet an ISP has assigned to a user, so we have to make an educuated guess. The default value is 56, corresponding to a /56 subnet. The valid range is 1-128, but typically ISPs assign subnets in the range of 32-64, with 64 being the most common. The validation check (which can be disabled) will warn for values outside the 32-64 range. Smaller values block larger ranges of IPs at once. 56 is a moderately aggressive default. It may be increased to if users are being incorrectly blocked (try 60 or 64), or decreased if you are seeing evidence of abuse. 64, 60 (Comcast), 56, and 48 are all common values used by various ISPs. The option may also be set to a function that returns the value if you want to apply different subnets to different users. (It’s not always possible to know what subnet a given user has, but you could make an educuated guess based on their ISP - see the example below.) Set to false to disable and always use the IP without masking. This example uses the node.js built-in net.BlockList to apply different subnets to different IP ranges:
import { BlockList } from 'node:net'
// or
// const { BlockList } = require('node:net')

// Comcast defaults to /64 but allows customers to request /60
// (note that this is a non-exhaustive list, there are many more)
const networks60 = new BlockList()
networks60.addSubnet('2a0c:93c0:10::', 44, 'ipv6')
networks60.addSubnet('2a0c:93c0:6000::', 48, 'ipv6')
networks60.addSubnet('2a0c:93c0:6002::', 48, 'ipv6')

// AWS allows customers to request up to a /44!
// (the full list is at https://ip-ranges.amazonaws.com/ip-ranges.json)
const networks44 = new BlockList()
networks44.addSubnet('2600:1f69:7400::', 40, 'ipv6')

app.use(
	rateLimit({
		ipv6Subnet: function (req, res) {
			if (networks60.check(req.ip, 'ipv6')) return 60
			if (networks44.check(req.ip, 'ipv6')) return 44
			return 56 // fallback
		},
		// ...
	}),
)

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.