What resilix is
Why this exists
JavaScript has fault handling. Its load limiting is locked inside two RPC clients — hedging and retry budgets only in @grpc/grpc-js, adaptive throttling only in the AWS SDK, ~90M downloads a week between them, and unavailable to anyone calling a plain HTTP API, a database or a queue.
Two failure modes motivated this library, both from production:
1. Your upstream degrades without erroring. A provider went from p50 0.35s / p95 0.9s to p50 10.4s / p95 15.3s — roughly 25–30× slower with a completely flat error rate. A failure-rate circuit breaker is blind to that until calls start timing out. resilix trips on slow-call rate, a dimension no other JavaScript breaker has.
2. Healthy traffic contains a lot of 4xx. On a good day, 13–18% of calls to a validating upstream returned 4xx. Any breaker whose failure predicate is "did the promise reject?" opens because customers submitted bad input. resilix classifies outcomes into verdicts, so a 4xx is answered — healthy — while a 429 is overload: not a failure, but still a load signal.
Design commitments
- Zero runtime dependencies, no I/O in core. A policy decision costs microseconds and cannot itself fail.
- Time is injected. Every temporal behaviour is deterministically testable; the test suite has no real timers and no
sleep(). - Nothing at module scope. No timers, no
AbortController, no random values at import time — which is what makes some libraries crashwrangler devon import. - O(1) per call. The window keeps running counters, so rates never iterate and eviction is a tail advance, not a scan. Typed arrays, preallocated, no steady-state allocation.
- Bounded key registry. Per-host state has a TTL and a hard cap, so tenant- or attacker-influenced keys cannot leak memory.
- No distributed state. Cross-instance ejection belongs to the service mesh.
snapshot()/hydrate()cover the serverless case, which is what people actually need — and they are origin-safe: every serialised time is relative, and idle time between processes is accounted for, so a rehydrated window ages correctly instead of coming back looking fresh.
Where to go next
| Getting started | install, your first pipeline, and the two mistakes that bite immediately |
| The verdict model | the idea the rest of the library is built on |
| Design decisions | why it is shaped this way, including what was rejected |