rateLimit

tcmts.server.rateLimit · #igar4ips · term · runs anywhere

Allow max calls per per seconds for key (e.g. "login:" + request().ip); beyond that, throws a 429.

import { HttpError, rateWindows } from "#codebase/tcmts/server";

export function rateLimit(key: string, opts: { max: number; per: number }): void {
  const now = Date.now();
  const since = now - opts.per * 1000;
  const hits = (rateWindows.get(key) ?? []).filter((t) => t > since);
  if (hits.length >= opts.max) {
    const retryAfter = Math.max(1, Math.ceil((hits[0]! - since) / 1000));
    rateWindows.set(key, hits);
    throw new HttpError(429, `too many attempts; try again in ${retryAfter}s`, { retryAfter });
  }
  hits.push(now);
  rateWindows.set(key, hits);
  if (rateWindows.size > 10_000)
    for (const [k, v] of rateWindows) if (!v.some((t) => t > since)) rateWindows.delete(k);
}

uses

used by