Skip to content

Uniqueness and clocks ​

Within one generator ​

An unmasked generator never reuses its timestamp/sequence pair while that instance remains alive. When the clock moves backwards, it retains the last logical timestamp and advances the sequence. When sequence capacity is exhausted, it advances logical time by one millisecond.

This avoids blocking the event loop while waiting for the physical clock. A fixed or heavily loaded clock can leave the logical timestamp ahead of real time. Expiry uses the physical clock, so such IDs start aging when real time catches up. A timestamp that cannot fit the configured field throws instead of wrapping.

Random and entropy fields sit above the sequence field. IDs in the same millisecond are not guaranteed to increase numerically. The timestamp groups IDs chronologically; the random fields also prevent Base62 strings from being a reliable lexicographic time index.

Across generators and restarts ​

Assign unique machine IDs to concurrent instances and ensure your deployment does not duplicate assignments. Machine IDs derived from network interfaces are hashes and can collide. Random selection cannot guarantee unique assignments.

The library does not persist generator state. Restarting a generator with the same machine ID can reuse timestamp/sequence pairs. Random bits reduce collision probability but do not eliminate it. Use a unique database constraint and application retry policy when absolute uniqueness matters.

Wall-clock and monotonic time ​

The default uses Unix milliseconds from Date.now(). The 42-bit default timestamp stores values through 2 ** 42 - 1 milliseconds since the epoch.

useWallClock: false uses Node's process.hrtime.bigint() converted to milliseconds. Its origin is not a portable creation date. Do not mix clocks, decode monotonic IDs as dates, or compare their age on another host. Migration notes cover older nanosecond-based IDs.

Choosing a standard ​

RequirementHybrid ID
Custom machine fieldConfigurable, 12 bits by default
Storage size81 bits by default; exceeds a 64-bit integer
Standard UUID formatCustom integer format; not a UUID
Creation time and ageWall-clock IDs with masking disabled
Portable layout discoveryKeep configuration separately
Authorization or secret tokensUse application authorization and a separate secret-token design

Choose a standard UUID when required by your database, tooling, or interoperability contract.

Released under the MIT License.