Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/AmeyaBorkar/throttlekit/llms.txt

Use this file to discover all available pages before exploring further.

twoTier constructs a limiter that fronts a distributed (L2) store with an in-process (L1) local tier. The coordination mode controls the consistency/throughput trade-off: strict is exactly equivalent to a plain rateLimit over L2; cached-deny eliminates round trips for already-blocked keys; and leased drives steady-state network cost toward approximately one round trip per batch requests, with a proven bounded global overshoot.
import { twoTier, gcra } from "throttlekit";
import { RedisStore } from "throttlekit/redis";

const limiter = twoTier({
  strategy: gcra({ limit: 1_000, periodMs: 60_000 }),
  l2: new RedisStore({ client }),
  mode: "leased",
  lease: { batch: 50, windowCoupled: true },
});

const decision = await limiter.check("tenant:acme");

Signature

function twoTier<S = unknown>(options: TwoTierOptions<S>): Limiter

Options

strategy
Strategy<S>
required
The algorithm enforced at L2 (and, in leased mode, the unit of the leased budget). Any built-in strategy works; custom strategies work in strict and cached-deny modes.
l2
Store
required
The distributed backing store. Typically a RedisStore or PostgresStore. The caller owns this store — close() on the returned limiter does not close it.
mode
TwoTierMode
required
Coordination mode. One of "strict", "cached-deny", or "leased". See details below.
lease
LeaseOptions
Required when mode is "leased". Controls the batch size and window-coupling behavior.
l1
L1Options
Local-tier tuning.
clock
Clock
Injected time source. Defaults to the system clock.
prefix
string
Key namespace prepended to every store key as prefix:key.

Coordination Modes

"strict"

Every check consults L2 directly. Globally exact (one round trip per request). Under the hood this is equivalent to rateLimit({ strategy, store: l2, clock, prefix }).

"cached-deny"

Allowed traffic flows through L2 unmodified. When L2 issues a denial, its retryAfterMs is cached locally and served directly for subsequent checks within that window, eliminating L2 load from repeated blocked requests. Globally exact for allowed traffic.

"leased"

Each node leases a batch-sized budget from L2 and serves requests locally until the budget is exhausted. Steady-state network cost is approximately one round trip per batch requests. Concurrent misses on the same key are coalesced onto a single in-flight lease to prevent L2 stampedes. The global overshoot bound is ≤ L × batch (where L is the live node count). With windowCoupled: true the bound tightens to exactly Limit independent of node count.

Return Value

Returns a Limiter with the same interface as rateLimit. Note that checkSync and checkManySync are not available on a twoTier limiter in cached-deny or leased mode (L2 access is inherently asynchronous) — they throw a ThrottleKitError if called.

Helper Functions

eoqOptimum(orderCost, strandPenalty, demand)

function eoqOptimum(orderCost: number, strandPenalty: number, demand: number): number
The closed-form Economic Order Quantity optimum: √(2 · orderCost · demand / strandPenalty). The target the adaptive lease sizer descends toward. Pure math, no state.

leaseSizer(options)

function leaseSizer(options: LeaseSizerOptions): LeaseSizer
Build a per-key online lease sizer. At each window boundary, feed it the demand that key served (observe(demand)) and read back the batch for the next window (size()). @experimental.

predictiveLeaseSizer(options)

function predictiveLeaseSizer(options: PredictiveLeaseSizerOptions): PredictiveLeaseSizer
A prediction-augmented lease sizer that blends a per-window demand forecast with the robust leaseSizer via a Hedge meta-learner. @experimental.

regionFairPool(options)

function regionFairPool(options: RegionFairPoolOptions): RegionFairPool
An in-process, synchronous weighted-fair pool over regions (a WFE over region identities). Used as the cross-region layer in federatedWeightedFairEscrow. @experimental.

weightedFairEscrow(options)

function weightedFairEscrow(options: WeightedFairEscrowOptions): WeightedFairEscrowLimiter
A two-tier limiter where L2 leases are distributed across tenants using weighted max-min fairness (GALE Pillar 4). No tenant can be starved below its weighted floor by a flood from others. @experimental.

federatedWeightedFairEscrow(options)

function federatedWeightedFairEscrow(
  options: FederatedWeightedFairEscrowOptions
): FederatedWeightedFairEscrowLimiter
Lifts weightedFairEscrow across regions: per-region tenant WFE composed with a shared cross-region regionFairPool into a global weighted-max-min guarantee. @experimental.

Examples

Leased mode with window coupling

import { twoTier, gcra } from "throttlekit";
import { RedisStore } from "throttlekit/redis";

const store = new RedisStore({ client });

const limiter = twoTier({
  strategy: gcra({ limit: 10_000, periodMs: 60_000 }),
  l2: store,
  mode: "leased",
  lease: {
    batch: 100,
    windowCoupled: true,  // eliminates cross-window overshoot
    lowWater: 10,         // proactive refill at 10 remaining
    returnIdleAfterMs: 30_000,
  },
  l1: { maxKeys: 50_000 },
});

Cached-deny to absorb abusive clients

import { twoTier, fixedWindow } from "throttlekit";

const limiter = twoTier({
  strategy: fixedWindow({ limit: 100, windowMs: 60_000 }),
  l2: redisStore,
  mode: "cached-deny",
  // A blocked client stops hitting Redis for the duration of its retryAfterMs
});

Adaptive lease sizing (GALE Pillar 2)

import { twoTier, gcra } from "throttlekit";

const limiter = twoTier({
  strategy: gcra({ limit: 5_000, periodMs: 60_000 }),
  l2: redisStore,
  mode: "leased",
  lease: {
    adaptive: {
      orderCost: 1,       // cost of one L2 round trip
      strandPenalty: 0.5, // cost of stranded (unexpired) credits
    },
    windowCoupled: true,
  },
});

Build docs developers (and LLMs) love