Pacer
Decide what runs, when it runs, and what happens under pressure.
Pacer gives noisy events and async work a shared timing model: debounce, throttle, rate limiting, queues, and batches with observable state.
events
24
executions
2
pending
0
The latest value · waits for quiet
Policy map
Choose by what you can afford to lose.
Each policy answers a different product question. Pick one by deciding whether work may be dropped, delayed, sampled, or grouped—not by reaching for the timer you remember.
Debounce
keepsThe latest value
tradeoffWaits for quiet
Search inputThrottle
keepsA regular sample
tradeoffDrops the middle
Pointer updatesRate limit
keepsCalls inside the allowance
tradeoffRejects excess calls
API requestsQueue
keepsEvery task
tradeoffControls concurrency
File uploadsBatch
keepsEvery item
tradeoffGroups executions
Analytics writesAsync traffic control
Backpressure becomes product behavior.
Queues turn a pile of promises into explicit traffic: order, priority, concurrency, expiration, retries, and cancellation all have a place in the model.
order
priority
workers
2
retries
2 max
concurrency / 2
status
settled
executions
128
pending
0
last run
42ms
queue.store.subscribe(state => {
renderProgress(state.executionCount)
})
Observable by design
The timer is no longer a black box.
Timing state should not disappear inside a closure. Subscribe to execution counts, pending work, errors, and status; inspect the same model in devtools; adopt the core alone when that is all you need.