UXID.Monotonic (UXID v2.6.0)
View SourceProcess-local monotonic counter backing UXID's monotonic: mode.
All state lives in the process dictionary — no GenServer, no ETS, no shared
state — so callers stay async: true safe. Each BEAM process maintains its
own independent sequence per {prefix, rand_size}.
The random field is treated as one big-endian unsigned integer. The first ID
in a given millisecond seeds it with full CSPRNG bytes; each subsequent ID in
the same millisecond advances it by a random positive step drawn from the
CSPRNG. Because the step is always >= 1 the sequence is strictly increasing,
so IDs stay unique and — since the encoding is big-endian and the Crockford
alphabet is ASCII-monotonic — integer order equals encoded lexical order,
preserving K-sortability within the millisecond.
The step is uniform over [1, 2^(bits/2)] where bits is the field width, so
the next value is spread across a window of size ~2^(bits/2) instead of being
exactly +1. This is a mitigation, not cryptographic unpredictability: it
removes trivial …0004 → …0005 enumeration and raises single-shot guess cost
from certainty to ~1/2^(bits/2), but consecutive values still lie in a bounded
window ahead. Low-entropy sizes (:small = 16 bits) remain low-entropy — don't
use small/medium monotonic IDs as externally-enumerable, security-sensitive
identifiers.
Summary
Functions
Returns {time, rand_bytes} for a monotonic generation.
Clears the counter for {prefix, rand_size} in the current process.
Functions
Returns {time, rand_bytes} for a monotonic generation.
time may be bumped forward by 1ms if the counter overflowed the field
within a single millisecond. rand_bytes is exactly rand_size bytes.
Clears the counter for {prefix, rand_size} in the current process.
Intended for tests and utilities; generation never requires it.