ded/express-limiter
Rate limiting middleware for Express
{ "createdAt": "2014-03-23T15:24:39Z", "defaultBranch": "master", "description": "Rate limiting middleware for Express", "fullName": "ded/express-limiter", "homepage": null, "language": "JavaScript", "name": "express-limiter", "pushedAt": "2019-04-12T23:41:10Z", "stargazersCount": 423, "topics": [], "updatedAt": "2025-09-12T10:37:36Z", "url": "https://github.com/ded/express-limiter"}Express rate-limiter
Section titled “Express rate-limiter”Rate limiting middleware for Express applications built on redis
npm install express-limiter --savevar express = require('express')var app = express()var client = require('redis').createClient()
var limiter = require('express-limiter')(app, client)
/** * you may also pass it an Express 4.0 `Router` * * router = express.Router() * limiter = require('express-limiter')(router, client) */
limiter({ path: '/api/action', method: 'get', lookup: ['connection.remoteAddress'], // 150 requests per hour total: 150, expire: 1000 * 60 * 60})
app.get('/api/action', function (req, res) { res.send(200, 'ok')})API options
Section titled “API options”limiter(options)path:Stringoptional route path to the requestmethod:Stringoptional http method. acceptsget,post,put,delete, and of course Express’alllookup:Function|String|Array.<String>value lookup on the request object. Can be a single value, array or function. See [examples]!(#examples) for common usagestotal:Numberallowed number of requests before getting rate limitedexpire:Numberamount of time inmsbefore the rate-limited is resetwhitelist:function(req)optional param allowing the ability to whitelist. returnboolean,trueto whitelist,falseto passthru to limiter.skipHeaders:Booleanwhether to skip sending HTTP headers for rate limits ()ignoreErrors:Booleanwhether errors generated from redis should allow the middleware to call next(). Defaults to false.onRateLimited:Functioncalled when a request exceeds the configured rate limit.
Examples
Section titled “Examples”// limit by IP addresslimiter({ ... lookup: 'connection.remoteAddress' ...})
// or if you are behind a trusted proxy (like nginx)limiter({ lookup: 'headers.x-forwarded-for'})
// by user (assuming a user is logged in with a valid id)limiter({ lookup: 'user.id'})
// limit your entire applimiter({ path: '*', method: 'all', lookup: 'connection.remoteAddress'})
// limit users on same IPlimiter({ path: '*', method: 'all', lookup: ['user.id', 'connection.remoteAddress']})
// whitelist user adminslimiter({ path: '/delete/thing', method: 'post', lookup: 'user.id', whitelist: function (req) { return !!req.user.is_admin }})
// skip sending HTTP limit headerslimiter({ path: '/delete/thing', method: 'post', lookup: 'user.id', whitelist: function (req) { return !!req.user.is_admin }, skipHeaders: true})
// call a custom limit handlerlimiter({ path: '*', method: 'all', lookup: 'connection.remoteAddress', onRateLimited: function (req, res, next) { next({ message: 'Rate limit exceeded', status: 429 }) }})
// with a function for dynamic-nesslimiter({ lookup: function(req, res, opts, next) { if (validApiKey(req.query.api_key)) { opts.lookup = 'query.api_key' opts.total = 100 } else { opts.lookup = 'connection.remoteAddress' opts.total = 10 } return next() }})as direct middleware
Section titled “as direct middleware”app.post('/user/update', limiter({ lookup: 'user.id' }), function (req, res) { User.find(req.user.id).update(function (err) { if (err) next(err) else res.send('ok') })})License MIT
Section titled “License MIT”Happy Rate Limiting!