throttlekit
Changelog
Every release, in one place.

Curated highlights across the three published packages, newest first. Each links out to its full CHANGELOG.md on GitHub, and you can see the at-a-glance shipped state on the status board.

throttlekit

The core library — algorithms, stores, adapters, the two engines.

v1.7.0npm
1.7.0 hardening
  • A decision-finiteness invariant now applies across every strategy: a construction parameter that would make a Decision field (limit/remaining/resetAt/retryAfterMs) non-finite throws a RangeError at construction instead of emitting a malformed value, closed in gcra, tokenBucket, and fixedWindow/slidingWindow/quota. The worst case was leakyBucket, where a non-finite delayMs made schedule() call sleep(Infinity) and hang forever: a silent hang, not just a bad number.
  • New hard limits close DoS/overflow vectors: the zero-dependency YAML/JSON config parser caps block-nesting depth at 64 (a deeply nested untrusted config could previously stack-overflow), a per-request cost above Number.MAX_SAFE_INTEGER is now rejected (it previously overflowed internal arithmetic to a non-finite value), slidingWindow.buckets is capped at 100,000, and a decoded sketch snapshot with a poisoned/non-finite total is rejected on decode and ignored on merge.
  • Internal: a new fuzzing, mutation-testing, and model-based-testing layer found these (Stryker mutation score on the core decision math went 65.4% → 77.5%, and a live-store CI gate now runs on every push). Minor bump, not patch: a handful of previously-garbage-returning absurd option values now throw, no valid input's behavior changed.
1.6.1 performance
  • multiRateLimit.checkSync is about 40% faster on composite dimensions (2-dim 4968→2968 ns/op, 3-dim 7507→4599 ns/op) by skipping structuredClone for dimensions whose state is an immutable primitive (the GCRA default); only object/array states still clone.
  • weightedFairEscrow grant is about 15% faster (182→155 ns/op) via an O(1) running Σweight/Σused aggregate, gated on integer weights/costs, falling back to the exact rescan the instant a fractional value appears.
  • RedisStore now pipelines the ttlFloorMs floor into the strategy eval in one round trip for pipeline-capable clients; PostgresCoordinator drops a redundant SELECT...FOR UPDATE via RETURNING.
  • All decisions are byte-identical before/after: this is an internal perf pass, not a behavior change.
1.6.0 audit sweep
  • A multi-agent correctness/security audit — every fix reproduced on real code and pinned by a regression that failed on the prior commit.
  • Fixes: concurrency-coordinator over-eviction (now anchors to the Redis server clock), two window-roll over-admits (federation lease + twoTier low-water refill), and a multiRateLimit Redis-prefix mismatch that made reset() a no-op.
  • New opt-in options: RedisStore.ttlFloorMs, RedisConcurrencyCoordinator.useServerTime, and a per-instance sketch seed.
1.5.0
  • Tier-2 fleet leasing — LeaseSpender spends a leased slice of a global budget locally, refreshing once per batch (proven byte-identical to the core leased path, golden-vector pinned).
  • Store-authoritative lease window (leaseWindowed) eliminates node↔store clock skew.
1.4.0
  • Policy Plans (throttlekit/policy) — a terraform plan for limits: replay recorded traffic vs a candidate → the allow↔deny diff, gate-able in CI.
  • Store-backed cross-region fair escrow (RedisRegionFairPool) — weighted-max-min across separate region processes.
1.3.0
  • What-If Replay testkit — record a leaf limiter's decisions, replay a candidate, read the flip ledger. Fail-loud throughout.
1.2.0
  • New stable OTel metric denies_by_axis{lane} — break unified-admission denials down by axis in Grafana.
1.1.0
  • In-process telemetry (admissionTap / withAdmissionAnalytics) — the binding-axis signal that powers ThrottleKit Lens.
1.0.0 API frozen
  • The API is frozen under SemVer — mechanically enforced (type-surface tests + publint / attw on every push).
  • STABILITY.md (the v1 promise) and BENCH.md (measured, reproducible numbers) ship with the package.

throttlekit-server

The gRPC service door + ThrottleKit Lens — reach the same limiter from any language.

v0.4.4npm
0.4.4 performance
  • The RateLimiter.Check gRPC handler is about 25% faster (898→675 ns/op, 1.11M→1.48M ops/s in-process) by building the server enforcer with emit:false, so the RateLimit-* header set the gRPC path discards is never computed.
  • Capture: the in-process collision witness now uses an unkeyed SHA-256 (it never persists), and the encrypted segment store is swept once per flush batch instead of once per write (O(K×N) → O(N)).
  • Cost Room validates and sorts the weighted-fair-escrow tenant roster once per snapshot frame instead of twice.
0.4.3
  • Audit fixes: Monitor safeStringify DAG false-positive, a startup banner that mislabeled a downgraded channel as mTLS, capture SegmentStore.read O(N)→O(1), and clarified Admit cost semantics.
0.4.2 security
  • Lease ids are now 128-bit random capability tokens (was a guessable global counter — a slot-hijacking vector).
  • Monitor GetSnapshot no longer crashes on a non-serializable custom stat; an authorized capture export that fails mid-flight is now audited.
0.4.1
  • Replay what-if no longer misclassifies distributed policies (federated / fleetBudget / distributedConcurrency / federatedFairEscrow) as plain leaf-rate.
0.4.0
  • Tier-2 Fleet lease door (Fleet.Reserve) — a high-throughput client leases a slice of a federated: budget and spends it locally; loopback-only until --fleet-secret.
  • Store-authoritative lease window; clean startup-drain and --monitor off fixes.
0.3.0
  • Four fleet features over existing RPCs — federated / federatedFairEscrow (Check), fleetBudget (Debit), distributedConcurrency (Admit) — no client change, no wire change.
  • Read-only Monitor door + Prometheus /metrics + standard gRPC health.
  • Policy Plans: the policy plan CLI and a --tui Plan tab.
0.2.0
  • Deterministic What-If Replay tab — how many requests a config change would flip, against live traffic.
0.1.0 wire frozen
  • Graduated from experimental: the gRPC wire is frozen and conformance-tested against the golden vectors.
  • Opt-in, AES-256-GCM-encrypted, redacted decision capture with a fail-closed audited CLI.
0.1.0-experimental.6
  • Monitoring moved to a built-in, zero-dependency terminal dashboard (--tui) — ThrottleKit Lens.

throttlekit-py

The reference Python client — every axis, bit-for-bit against the Node oracle.

v0.5.1PyPI
0.5.1
  • slots=True on the per-call frozen dataclasses (Decision, Forecast, Lease, LeaseGrant) roughly halves the transported decision's footprint (160 → 72 bytes).
  • The Redis backend precomputes its ARGV template once per backend instance instead of rebuilding it per call, for both sync and async.
  • The lease-spend cost guard is inlined, and the adapter checker's sync/async nature is classified once at construction instead of per request.
0.5.0
  • Tier-2 fleet leasing (FleetBackend / LeasedLimiter) + a MonitorBackend snapshot client; lease vectors byte-verified.
  • A full runnable examples/ set — one script per axis (rate, leased, cost, concurrency, unified, FastAPI).
0.4.0
  • Async backends (AsyncServiceBackend / AsyncRedisBackend).
  • @rate_limit decorator, decision_headers, and FastAPI / Starlette / Django / Flask adapters.
0.3.0
  • admit() reaches the concurrency / unified axis over the service door (Door C).
0.2.0
  • debit() for the cost axis — windowed token budgets over the service door (Door B).
0.1.0
  • Initial release: ServiceBackend (gRPC) + RedisBackend, the rate strategies, the frozen types, and the cross-language conformance suite.