AK / PORTFOLIOWork
Case [01]2026

A traffic workbench that makes four rate-limiting algorithms visible.

RateLab injects steady, bursty, and random traffic into deterministic limiters, then exposes every allow, deny, quota, retry clock, latency, and HTTP 429 decision in one inspectable interface.

Role
Design + Engineering (solo, open source)
Stack
ReactTypeScriptViteFastifyVitestNode.js
Timeline
2026
Status
Open source / v0.1.0
Ownership
Solo full-stack design + engineering
Outcome
4 algorithms, 3 traffic patterns, one inspectable HTTP contract

Context

A rate limiter answers a deceptively small question: may this identity consume a protected resource now? The answer depends on a policy, current state, and time. Reading an algorithm description explains the formula, but it does not make boundary spikes, refill behavior, rolling fairness, or retry timing easy to feel.

RateLab is an interactive workbench for making those differences visible. It combines a React experiment dashboard with a Fastify API and deterministic limiter implementations, so the same traffic can be applied to four state models and inspected decision by decision.

Constraint

  • Traffic shape changes the result. An average request rate hides the difference between steady load, concurrent bursts, and uneven jitter.
  • Time is part of the state. Fixed boundaries, timestamp expiry, continuous refill, and continuous drain need deterministic clocks to be testable.
  • The HTTP contract matters. A denied decision is not only a red UI state; it must return 429 Too Many Requests, remaining quota, and useful retry timing.
  • A lab must state its limits. RateLab stores state inside one Fastify process. Restarting clears it, and multiple instances do not share quota.

Move

  • Four algorithms behind one decision interface. Fixed window, sliding window log, token bucket, and leaky bucket all return allowed, remaining, and retryAfterMs while preserving their different state models.
  • Three traffic generators. Steady traffic shows equilibrium, burst traffic exposes capacity and race behavior, and randomized jitter reveals timing sensitivity.
  • An inspectable request path. The dashboard shows ingress rate, passed and dropped decisions, p95 latency, pass rate, quota cells, refill or drain clocks, the last 24 frames, and a selectable wire trace.
  • A real HTTP boundary. POST /api/check validates identity key, algorithm, capacity, and window. Denied requests receive HTTP 429 plus RateLimit-Limit, RateLimit-Remaining, and Retry-After headers.
  • Deterministic tests. A controlled clock verifies window resets, rolling expiry, refill behavior, and the invariant that remaining quota never becomes negative.
  • Documentation as part of the product. The included field manual covers the mental model, parameters, algorithm tradeoffs, traffic recipes, observability panels, HTTP contract, and production concerns.

Result

  • Four algorithms can be compared through the same policy and response contract.
  • Three offered-load patterns make boundary behavior and burst tolerance visible instead of theoretical.
  • Every captured frame exposes the algorithm, decision, remaining quota, retry time, response status, and measured latency.
  • The monorepo includes a React/Vite web application, Fastify API, limiter engine, Vitest tests, build and lint commands, and an MIT license.

What I'd change

  • Move state to Redis with atomic policies. Transactions or Lua scripts are required before multiple API instances can share quota without overspending it.
  • Make failure behavior configurable. A production consumer needs an explicit fail-open, fail-closed, or local-fallback policy when the datastore is unavailable.
  • Use stronger key composition. Per-IP limits can punish users behind NAT; user-only keys can let one route consume every allowance. Tenant, identity, and route often belong in the key together.
  • Expire inactive state deliberately. Sliding logs need trimming and bucket records need TTLs derived from refill time.
  • Track production signals. Decisions, saturation, datastore latency, retry duration, hot keys, and policy version should be first-class telemetry.

Command palette

Search and jump to any page.