distkit
Concepts

Strict vs lax

The consistency trade-off that runs through distkit's counters.

distkit's counters come in two flavors, and the same split shows up again in the instance-aware counters. Understanding it once explains both.

Strict: correctness first

A strict counter executes every operation as an atomic Lua script on Redis. Each call is one round-trip, and a read always reflects the latest write from anywhere in the cluster.

Use strict counters when an off-by-one matters: billing, inventory, quota enforcement, anything you would be uncomfortable approximating.

Lax: throughput first

A lax counter buffers increments in a local DashMap and flushes them to Redis in batched pipelines on an interval (allowed_lag, default ~20 ms). Increments return almost instantly because they never touch the network on the hot path. Reads return the local view (remote_total + pending_delta), which is always consistent within the same process but may lag what other processes have flushed.

Use lax counters for analytics and high-throughput metrics, where a few milliseconds of cross-process lag is fine and per-call Redis I/O would be the bottleneck.

Side by side

StrictCounterLaxCounterStrictInstanceAwareCounterLaxInstanceAwareCounter
ConsistencyImmediateEventual (~20 ms default)ImmediateEventual (flush_interval)
inc latencyRedis round-tripSub-microsecond (warm path)Redis round-tripSub-microsecond (warm path)
Redis I/OEvery operationBatched on intervalEvery incBatched on interval
set / delImmediateImmediateImmediate (bumps epoch)Flushes pending delta, then immediate
Per-instance trackingNoNoYesYes
Dead-instance cleanupNoNoYesYes
Feature flagcounter (default)counter (default)instance-aware-counterinstance-aware-counter
Use caseBilling, inventory, exact global countAnalytics, high-throughput metricsConnection counts, exact live metricsHigh-frequency per-node throughput metrics

A rule of thumb

Reach for strict by default. Switch to lax only when you have measured that per-call Redis round-trips are your bottleneck and you can tolerate a small, bounded lag.

See Counters for the API and Instance-aware counters for the per-instance variants.