# `UXID.Monotonic`
[🔗](https://github.com/riddler/uxid-ex/blob/v2.9.1/lib/uxid/monotonic.ex#L1)

Process-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.

# `next`

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.

# `reset`

Clears the counter for `{prefix, rand_size}` in the current process.

Intended for tests and utilities; generation never requires it.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
