PRODUCTION READY · 3 ALGORITHMS · ATOMIC LUA SCRIPTS · REAL-TIME DASHBOARD

Distributed rate limiting
done right.

Express middleware that identifies callers by API key or IP, runs an atomic Lua script in Redis, and allows or blocks — with zero race conditions across any number of instances.

No race conditions// Lua atomic ops
3 algorithms// fixed · sliding · token
Fail-safe// open or closed per route
24 tests// real Redis in CI

INTERACTIVE DEMO

Fire real requests. Watch it block.

Hits the live production API on Render + Upstash Redis. Press ×8 to drain the limit and trigger a 429.

ALGORITHM
Fixed Window
GET /demo/public

Divides time into fixed buckets. Fast and simple. Vulnerable to boundary burst attacks.

REMAINING5 / 5
— no requests yet —
ALGORITHM
Sliding Window
GET /demo/authenticated

Always looks at the last N milliseconds using a Redis sorted set. Eliminates boundary edge cases.

REMAINING5 / 5
— no requests yet —
ALGORITHM
Token Bucket
POST /demo/expensive

Tokens refill over time. Allows bursting up to capacity then throttles to refill rate. Used by Stripe.

REMAINING5 / 5
— no requests yet —

Every request above is tracked live on the dashboard

Real-time chart · allowed vs blocked · top blocked identifiers · SSE live feed

OPEN DASHBOARD →

HOW IT WORKS

01
Identify caller

x-api-key header takes priority. Falls back to x-forwarded-for then socket IP. Every caller gets an isolated Redis key.

02
Atomic Lua script

One script runs inside Redis. Read, decide, write — one indivisible operation. No race condition possible at any scale.

03
Headers always

X-RateLimit-Limit, Remaining, Reset on every response. Retry-After on every 429. Clients always know their state.

04
Fail safely

Redis down? Each route is configured fail-open or fail-closed independently. No silent failures, no surprise outages.

USAGE

One line to protect any route.

// protect any route in one line
app.use('/api', createRateLimiter({
  algorithm: 'sliding',
  limit: 100,
  windowMs: 60_000,
}));

// token bucket for burst-tolerant endpoints
app.post('/api/payment',
  createRateLimiter({
    algorithm: 'token',
    capacity: 10,
    refillRate: 2,
    failOpen: false,  // fail-closed on Redis outage
  }),
  paymentHandler
);

See it live.

Real-time charts, SSE event feed, top blocked identifiers.

VIEW SOURCE ↗OPEN DASHBOARD →