ThrottleKit ships a zero-dependency CLI with three operator commands: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.
benchmark for quick in-process performance measurement, doctor for environment and configuration checks, and replay for re-running a recorded traffic log against a limiter. All commands write to stdout/stderr and return standard UNIX exit codes (0 = success, 1 = failure, 2 = usage error).
benchmark — In-Process Micro-Benchmark
Runs a tight loop against each of the three single-state strategies (GCRA, token bucket, fixed window) on an in-process MemoryStore, measuring ops/second and nanoseconds per operation.
benchmark is strictly for orientation — it measures the in-process hot path with no store latency. Production performance depends on your store (Redis RTT, connection pool, etc.), key contention, and GC pressure. Use it to compare strategies, not to predict absolute throughput.doctor — Environment and Config Checks
Checks Node.js version (≥ 18 required), probes optional peer dependencies, and validates your .throttlekit.yaml or .throttlekit.json if one is present in the current working directory.
doctor exits 0 when all checks pass and 1 when at least one fails (Node < 18, or a YAML parse error).
replay — Re-Run a Decision Log
Reads a JSON-lines file where each line is { "key": string, "cost"?: number }, replays every line through a limiter, and prints a summary of allow/deny counts plus the top-10 denied keys.
Specifying the Limiter
From a config file (recommended for production):replay Flags
Path to a
.throttlekit.yaml or .throttlekit.json config file. Use with --name to select a specific limiter.Name of the limiter to use from the config file. Defaults to
"default".Strategy to use when
--config is not provided. One of gcra | fixedWindow | tokenBucket. Default gcra.Limit / capacity for the inline strategy. Default
100.Period for the inline strategy. Accepts
"1m", "30s", "1h", or a raw millisecond count. Default "1m".Log Format
Each line in the JSON-lines file must be a JSON object with at least akey field:
key, or have a non-positive/non-finite cost are silently skipped (replay is a forensic tool — one dirty row shouldn’t abort the run). Comment lines (starting with #) and blank lines are also skipped.
.throttlekit.yaml Config Format
The CLI (and loadConfig) reads a .throttlekit.yaml or .throttlekit.json with the following schema:
gcra, fixedWindow, tokenBucket.
The built-in YAML parser is a deliberately narrow, zero-dependency subset: block maps, scalars, and inline flow maps (
{ k: v }) only. It does not support block lists, anchors/aliases, multiline scalars, multi-document, or nested flow maps (e.g. { a: { b: 1 } } throws a parse error). Any value with a nested sub-object must be written as an indented block. This narrow grammar has no YAML-bomb attack surface.Loading the Config in Code
loadConfig auto-detects JSON (text starting with { or [) vs YAML. It builds independently-namespaced limiters — each limiter’s key is prefixed with its policy name by default.
throttlekit-server — gRPC Service with Lens TUI
The throttlekit-server binary starts the gRPC rate-limit service. Two flags are relevant for operations:
Path to a
.throttlekit.yaml or .throttlekit.json describing the limiters to serve.Launch the ThrottleKit Lens in-terminal dashboard. Renders live traffic stats, latency, fairness, capacity, and policy plan diffs across 8 tabbed views.
FAQ: How do I generate a replay log from production traffic?
FAQ: How do I generate a replay log from production traffic?
Wire
tapDecisions around your limiter and write each DecisionEvent as a JSON line to a file or log stream: { key: event.key, cost: event.cost }. For long-running services, rotate the file daily and keep a rolling window. The replay command can then re-run any window against a candidate config.FAQ: Can I use replay with a Redis-backed limiter?
FAQ: Can I use replay with a Redis-backed limiter?
Yes, via
--config. loadConfig accepts an injected store argument, so you can pass a RedisStore at load time. However, for forensic replay you almost always want an in-memory store (the default when no store is injected) so the replay is deterministic and isolated from live production state.FAQ: The doctor command reports a missing optional peer. Do I need to install it?
FAQ: The doctor command reports a missing optional peer. Do I need to install it?
No. Optional peers are probed with a dynamic import and listed with
◦ (not ✗) when absent. They are only needed if you use the corresponding feature: ioredis / redis for RedisStore, pg for PostgresStore, @opentelemetry/api for OTel instrumentation, and @nestjs/common for the NestJS adapter. If you don’t use those features, the message is purely informational.