The unique ID generator repeated itself after restart
A hypothetical ID service restarts, reuses worker number 42, and begins at sequence zero. The wall clock is slightly behind its pre-crash reading. A supposedly unique ID appears twice.
The bit layout was correct. The ownership and restart protocol were missing.
Count the namespace before claiming throughput
A common Snowflake-style layout uses a sign/reserved bit, 41 timestamp bits, 10 worker bits, and 12 sequence bits. The timestamp is milliseconds since a chosen epoch. The sequence distinguishes IDs within one worker's millisecond.
That provides 1,024 worker values and 4,096 sequence values per millisecond per worker. These are encoding ceilings, not measured generation throughput. Forty-one timestamp bits span roughly 69.7 years; reject overflow and plan epoch migration.
Is leasing each worker ID sufficient if an old worker pauses past lease expiry, then resumes generating locally?
Clock rollback needs an explicit outcome
Within one live worker, refuse time values earlier than its safe high-water mark, wait within a bounded policy, or use a logical progression that preserves the namespace contract. Sequence exhaustion also requires waiting or another allocation scheme. Avoid unbounded busy-spinning in an application event loop.
Restart must preserve or reconstruct the high-water mark and worker-allocation safety. Smooth clock correction reduces one risk but does not prove safe restoration from an old disk image. A restored counter or lease table can reissue old rights.
Alternatives include database sequences, centrally allocated ranges, and sufficiently random IDs. Ranges reduce coordination per ID but may leave gaps on crash. Random IDs avoid worker coordination at the cost of probabilistic collision reasoning and different index locality. Ordered IDs leak some creation-time information and can make range-partitioned writes hot.
Unique is not globally ordered
Two workers' clocks can differ. IDs sorted by embedded timestamp need not represent real-time completion order or causality. Use a log position or explicit ordering protocol when the business requires that order.
Serialize large integer IDs as decimal strings in JSON/JavaScript interfaces unless the entire path has a correct large-integer contract. JavaScript Number cannot exactly represent every integer above . Precision loss can make distinct 64-bit IDs compare equal before they ever reach the database.
Monitor worker ownership, clock rollback, sequence exhaustion, namespace lifetime, duplicate constraints, and restore procedures. A uniqueness constraint is valuable last-line detection, not a substitute for preventing collision under normal operation.
Mental model: an ID generator allocates disjoint pieces of a namespace. Time and worker ownership are part of the allocation protocol.
Transfer: gapless invoices
Finance asks for gapless invoice numbers. Would preallocating a million IDs to each worker satisfy it?
Source trail: 15-distributed-unique-id-generators. See the source map for consolidation and reference-retained material.