Token-bucket rate limiting middleware for WS-Kit
npm install @ws-kit/rate-limitToken-bucket rate limiting for WS-Kit with pluggable backends and ready-to-use key functions.
``bash`
npm install @ws-kit/rate-limit @ws-kit/memory @ws-kit/core
`typescript
import { createRouter } from "@ws-kit/core";
import { rateLimit, keyPerUserPerType } from "@ws-kit/rate-limit";
import { memoryRateLimiter } from "@ws-kit/memory";
const limiter = memoryRateLimiter({ capacity: 100, tokensPerSecond: 10 });
const router = createRouter().use(
rateLimit({
limiter,
key: keyPerUserPerType, // rl:tenant:user:type
cost: () => 1,
}),
);
`
- Memory (@ws-kit/memory) — Single-process dev/test. Zero dependencies. Optional prefix to isolate policies sharing a backend.@ws-kit/redis
- Redis () — Distributed, atomic via Lua and server clock. Use when running multiple pods/servers.
- Durable Objects — See Cloudflare adapter for serverless deployments.
- keyPerUserPerType (default): per-user, per-message-type fairness.keyPerUser
- : single bucket per user (lighter memory).key: (ctx) => "rl:tenant:user:type"
- Custom: ; include tenant/user/type as needed.cost
- : weight expensive operations (return ctx.type === "Compute" ? 10 : 1)."anon"
- Anonymous users: built-in keys fall back to , so guests share one bucket; use a custom key with IP/session when you need per-guest isolation.
`typescript`
interface RateLimitPolicy {
capacity: number; // max tokens
tokensPerSecond: number; // refill rate
prefix?: string; // optional key namespace
}
consume() returns { allowed: boolean; remaining: number; retryAfterMs: number | null; }. retryAfterMs is null when cost exceeds capacity.
- Memory adapter is not shared across processes; pick Redis/DO for multi-instance limits.
- Inject a clock into memoryRateLimiter()` for deterministic tests.
- Keep keys stable and short; prefix when sharing a backend across multiple policies.