-
Notifications
You must be signed in to change notification settings - Fork 0
Migrating
Ameya Borkar edited this page May 26, 2026
·
2 revisions
Drop-in paths from the two most common Node rate limiters, plus a few recipes.
// before
app.use(rateLimit({ windowMs: 60_000, limit: 100 }));
// after — GCRA by default (smooth pacing, no 2× boundary burst), same standards headers
import { expressRateLimit } from "throttlekit/express";
import { gcra } from "throttlekit";
app.use(expressRateLimit({ strategy: gcra({ limit: 100, periodMs: 60_000 }) }));
// want the classic window? swap in fixedWindow({ limit: 100, windowMs: 60_000 })// before — throws on exhaustion
try { await rl.consume(key); } catch { /* respond 429 */ }
// after — one atomic Lua round trip, a Decision object instead of throw-on-deny
import { rateLimit, gcra } from "throttlekit";
import { RedisStore } from "throttlekit/redis";
const limiter = rateLimit({ strategy: gcra({ limit: 100, periodMs: 60_000 }), store: new RedisStore({ client: redis }) });
const d = await limiter.check(key);
if (!d.allowed) { /* respond 429 with d.retryAfterMs */ }The main shape change is throw-on-deny → a Decision object: instead of try/catch, branch on d.allowed and read d.retryAfterMs / d.remaining / d.resetAt.
// Tiered plans (free / pro) by API key — one store, namespaced per tier
const limiters = {
free: rateLimit({ strategy: gcra({ limit: 60, periodMs: 60_000 }), store, prefix: "free" }),
pro: rateLimit({ strategy: gcra({ limit: 1_000, periodMs: 60_000 }), store, prefix: "pro" }),
};
const d = await limiters[planFor(req)].check(apiKeyOf(req));
// Cost-weighted endpoints — charge expensive routes more from the same budget
await limiter.check(apiKeyOf(req), routeIsExpensive(req) ? 5 : 1);- Per-IP and per-route in one round trip — see Advanced limiting.
- Tiered burst + sustained — compose two GCRA limiters (e.g. 10/sec and 1000/hour) and allow only if both pass.
-
Global limit across regions —
twoTierleased at a shared store; see Distributed & provable.
ThrottleKit · MIT · 1.0 — API frozen under SemVer (Stability)
- Getting Started
- Choosing a strategy
- Frameworks & the edge
- Distributed & provable
- Federation
- Scaling & the Fleet
- Unified admission
- Pillar 4 — Weighted Fair Escrow
- Middleware integration
- Distributed adaptive concurrency
- Advanced limiting
- Overload, fairness & DDoS
- Operations
- Monitoring — ThrottleKit Lens
- Policy Plans
- Replay
- Performance
- Migrating
- Polyglot & Python
- GALE & TALE