Express Slow Down
raw JSON → 3.1.0 verified Sat Apr 25 auth: no javascript
Basic rate-limiting middleware for Express that slows down responses rather than blocking them outright. Current stable version is 3.1.0, released as part of the express-rate-limit ecosystem. It is built on top of express-rate-limit and uses its stores, providing a familiar API for slowing repeated requests. Key differentiator: it delays requests after a threshold instead of rejecting them, making it suitable for public API endpoints where gradual throttling is preferred over hard blocks. Requires Node >= 16 and Express 4/5. Ships TypeScript types, supports ESM and CJS, and is actively maintained.
Common errors
error import slowDown from 'express-slow-down'; ^^^^^^^^ SyntaxError: The requested module 'express-slow-down' does not provide an export named 'default' ↓
cause Trying to default-import the module, but version 3.x only provides named export 'slowDown'.
fix
Use named import:
import { slowDown } from 'express-slow-down' error TypeError: slowDown is not a function ↓
cause Using `require('express-slow-down')` and calling the result as a function, but it exports an object with 'slowDown' method.
fix
Use:
const { slowDown } = require('express-slow-down') error Error: The 'delayMs' option must be a function that returns a number. Received number. ↓
cause Passing a static number for `delayMs` in version 2+, where it must be a function.
fix
Replace
delayMs: 1000 with delayMs: (hits) => hits * 1000 or similar function. error Error: The 'store' option must be an instance of a store that implements the 'Store' interface. ↓
cause Passing a plain object as a store without implementing all required methods.
fix
Use a store from express-rate-limit's compatible stores (e.g., rate-limit-memcached) or implement the Store interface.
Warnings
breaking Version 3.0.0 removed the default export; use named export 'slowDown' instead. ↓
fix Change `import slowDown from 'express-slow-down'` to `import { slowDown } from 'express-slow-down'`.
breaking Version 2.0.0 dropped support for Node < 16 and changed the API from `delayMs` as a number to a function. ↓
fix Update `delayMs` to be a function returning the delay in ms, and ensure Node version >= 16.
gotcha When using both express-rate-limit and express-slow-down with the same external store, you must create two separate store instances with different prefixes to avoid double-counting. ↓
fix Create separate store instances: `const store1 = new MemcachedStore({ prefix: 'rl:' }); const store2 = new MemcachedStore({ prefix: 'sd:' });`
deprecated The 'skipFailedRequests' option has been deprecated in favor of 'skip' function. ↓
fix Use the 'skip' function with a custom check instead of 'skipFailedRequests'.
Install
npm install express-slow-down yarn add express-slow-down pnpm add express-slow-down Imports
- slowDown wrong
import slowDown from 'express-slow-down'correctimport { slowDown } from 'express-slow-down' - slowDown wrong
const slowDown = require('express-slow-down')correctconst { slowDown } = require('express-slow-down') - slowDown (TypeScript) wrong
import { SlowDown } from 'express-slow-down' (wrong case)correctimport { slowDown } from 'express-slow-down'
Quickstart
import { slowDown } from 'express-slow-down';
import express from 'express';
const app = express();
const speedLimiter = slowDown({
windowMs: 15 * 60 * 1000, // 15 minutes
delayAfter: 5, // allow 5 requests per 15 minutes without delay
delayMs: (hits) => hits * 100, // add 100ms delay per hit after the 5th
});
app.use('/api', speedLimiter);
app.listen(3000);