Production-grade rate limiting middleware for Express.
3 algorithms. Redis-backed. Fail-open. Zero config to start.
import express from 'express'; import { gatekeeper } from '@sibilsoren/gatekeeper'; const app = express(); // 100 requests/min per IP app.use(gatekeeper()); // Strict auth limits app.post('/auth/login', gatekeeper({ limit: 5, window: '15m', })); app.listen(3000);
{
"error": "Too Many Requests",
"retryAfter": 30
}
Three battle-tested algorithms. Pick the right one for your use case.
Prevents boundary burst attacks by weighting the previous window. Best accuracy-to-memory ratio.
The simplest approach. Resets the counter at each window boundary. Fast and memory-efficient.
Allows controlled bursts. Tokens refill at a steady rate. Perfect for API billing and throttling.
npm install @sibilsoren/gatekeeper
For Redis support, also install ioredis
import { gatekeeper } from '@sibilsoren/gatekeeper'; // That's it. Zero config works. app.use(gatekeeper());
// Strict for auth app.post('/auth', gatekeeper({ limit: 5, window: '15m' })); // Generous for reads app.use('/api', gatekeeper({ limit: 1000, window: '1m' }));
import { RedisStore } from '@sibilsoren/gatekeeper'; import Redis from 'ioredis'; app.use(gatekeeper({ store: new RedisStore(new Redis()), }));
Redis down? Requests still flow. Your API stays up.
Lua scripts in Redis prevent race conditions. No double-counting.
X-RateLimit-Limit, Remaining, Reset, and Retry-After on every response.
Rate limit by IP, API key, user ID, or any custom function.
No runtime deps. ioredis is an optional peer dependency.
Works everywhere. TypeScript types included.
| Option | Type | Default | Description |
|---|---|---|---|
limit | number | 100 | Max requests per window |
window | string | number | "1m" | Window size ("30s", "5m", "1h", or ms) |
algorithm | string | "sliding-window" | "fixed-window" | "sliding-window" | "token-bucket" |
store | Store | MemoryStore | Storage backend (MemoryStore or RedisStore) |
keyGenerator | function | req.ip | Generate rate limit key from request |
skip | function | () => false | Skip rate limiting for certain requests |
message | string | "Too Many Requests" | Custom error message |
headers | boolean | true | Include X-RateLimit-* headers |
capacity | number | 100 | Token bucket capacity |
refillRate | number | 10 | Tokens per second (token bucket) |
express-rate-limit.Distributed. Atomic. Fail-open. Production-ready.
npm install @sibilsoren/gatekeeper