finds.dev← search

// the find

animir/node-rate-limiter-flexible

★ 3,566 · JavaScript · ISC · updated Jun 2026

Atomic and non-atomic counters and rate limiting tools. Limit resource access at any scale.

A rate limiting library for Node.js that wraps virtually every storage backend you'd want to use — Redis, Postgres, MySQL, SQLite, MongoDB, Memcached, DynamoDB, in-process memory, PM2 cluster. The unified API means you can switch backends without rewriting your limiting logic. Aimed at anyone who needs to protect endpoints from brute force or abuse without rolling their own atomic counter logic.

The in-memory block strategy is genuinely useful: once a key gets blocked, subsequent requests are rejected locally without hitting Redis at all, which matters when you're absorbing 100k req/s from a determined attacker. The insurance limiter fallback lets you define a secondary in-memory limiter that activates if the store goes down, so a Redis outage doesn't take your rate limiting with it. The fixed-window implementation staggers reset times per key rather than using a global wall-clock window, which prevents the thundering herd of everyone's limits resetting at the same second. Zero production dependencies is a real advantage — no supply chain surface to worry about.

The promise-based API uses reject for rate limit exceeded, which means every consumer has to wrap consume() in try/catch or .catch() to handle what is actually a normal, expected outcome — this is an unfortunate design choice that conflates errors with business logic. Sliding window / token bucket algorithms aren't native; fixed window is the only built-in algorithm, and if you need true sliding window semantics you have to compose them yourself or live with the boundary spike problem. The SQL backends (Postgres, MySQL, SQLite) create their own tables and manage expiry via background timeouts rather than native TTL, which means stale rows accumulate until clearExpiredByTimeout fires — a problem if you're running this at scale against a shared database. TypeScript types live in a single `types.d.ts` file rather than being co-located with the implementations, so autocomplete on advanced options like `inMemoryBlockOnConsumed` can be harder to trust.

View on GitHub →

// want more like this?

We dig through GitHub every week and send a few repos picked for what you actually care about — each with an honest take like this one.

Get finds in your inbox → Search again →