Open Source ยท MIT License

Protect your API.
Every request.

Production-grade rate limiting middleware for Express.
3 algorithms. Redis-backed. Fail-open. Zero config to start.

3 Algorithms
27 Tests
0 Runtime Deps
server.ts
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);
429 Too Many Requests
{
  "error": "Too Many Requests",
  "retryAfter": 30
}
Response Headers
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 42
Retry-After: 30
Algorithms

Choose your strategy.

Three battle-tested algorithms. Pick the right one for your use case.

๐ŸชŸ

Fixed Window

The simplest approach. Resets the counter at each window boundary. Fast and memory-efficient.

80/100
๐Ÿšซ 100/100
20/100
โšก Fastest ๐Ÿ“ฆ 1 counter/client
๐Ÿชฃ

Token Bucket

Allows controlled bursts. Tokens refill at a steady rate. Perfect for API billing and throttling.

๐Ÿช™ ๐Ÿช™ ๐Ÿช™ ๐Ÿช™ ๐Ÿช™ ๐Ÿช™
4/6 tokens ยท refills 2/sec
๐Ÿ’ฐ Great for billing ๐Ÿ”€ Variable cost
Usage

From zero to protected in 30 seconds.

01

Install

npm install @sibilsoren/gatekeeper

For Redis support, also install ioredis

02

Add middleware

import { gatekeeper } from '@sibilsoren/gatekeeper';

// That's it. Zero config works.
app.use(gatekeeper());
03

Customize per route

// Strict for auth
app.post('/auth', gatekeeper({
  limit: 5, window: '15m'
}));

// Generous for reads
app.use('/api', gatekeeper({
  limit: 1000, window: '1m'
}));
04

Scale with Redis

import { RedisStore } from '@sibilsoren/gatekeeper';
import Redis from 'ioredis';

app.use(gatekeeper({
  store: new RedisStore(new Redis()),
}));
Why Gatekeeper

Built for production. Not for demos.

๐Ÿ›ก๏ธ
Fail-Open

Redis down? Requests still flow. Your API stays up.

โš›๏ธ
Atomic Operations

Lua scripts in Redis prevent race conditions. No double-counting.

๐Ÿ“Š
Standard Headers

X-RateLimit-Limit, Remaining, Reset, and Retry-After on every response.

๐ŸŽฏ
Flexible Keys

Rate limit by IP, API key, user ID, or any custom function.

๐Ÿชถ
Zero Dependencies

No runtime deps. ioredis is an optional peer dependency.

๐Ÿ“ฆ
Dual ESM + CJS

Works everywhere. TypeScript types included.

Configuration

Every knob you need.

Option Type Default Description
limitnumber100Max requests per window
windowstring | number"1m"Window size ("30s", "5m", "1h", or ms)
algorithmstring"sliding-window""fixed-window" | "sliding-window" | "token-bucket"
storeStoreMemoryStoreStorage backend (MemoryStore or RedisStore)
keyGeneratorfunctionreq.ipGenerate rate limit key from request
skipfunction() => falseSkip rate limiting for certain requests
messagestring"Too Many Requests"Custom error message
headersbooleantrueInclude X-RateLimit-* headers
capacitynumber100Token bucket capacity
refillRatenumber10Tokens per second (token bucket)

Your API deserves better
than express-rate-limit.

Distributed. Atomic. Fail-open. Production-ready.

npm install @sibilsoren/gatekeeper