Rate limit
ingenium.rateLimit is a fixed-window rate limiter with an in-memory default store. The store interface is Promise-returning so a Redis-backed adapter fits cleanly.
Usage
app.use(ingenium.rateLimit({
windowMs: 60_000,
limit: 100,
// default keygen reads X-Forwarded-For - make sure trustProxy is set!
keyGenerator: (ctx) => ctx.ip,
skip: (ctx) => ctx.path.startsWith('/health'),
}))
Behavior
- Storage - fixed-window in-memory store (
MemoryStore) by default. The cleanup interval isunref()'d so it never holds the event loop alive. - Pluggable - implement the
RateLimitStoreinterface (Promise-returning) to back it with Redis or any other shared store. - Headers - sets
X-RateLimit-Limit,X-RateLimit-Remaining, andX-RateLimit-Reseton every response. - 429 response - sets
Retry-Afteron the rejection.
Note: The default keygen reads
X-Forwarded-Forviactx.ip. WithouttrustProxyconfigured correctly, an attacker can spoof the header and bypass the limit. SettrustProxybefore relying on rate limiting in production.
Multi-instance deploys
The in-memory store does not share state across pods. For multi-instance production, a Redis-backed adapter is the next P0 - see the roadmap.
Where to next?
- Trust proxy - required for the default keygen.
- Production hardening - the full prod wiring.
- Middleware - the dispatch model.
- Roadmap - Redis store status.