The identifier problem Snowflake addresses

Distributed services need distinct identifiers for records created concurrently across nodes. Twitter’s archived IdWorker.scala combines time, datacenter, worker, and sequence values in one ID. This lets a generator avoid a central allocation request for every ID, while leaving worker assignment and clock behavior as operational assumptions. The repository README says the public initial release was retired and the internal version was rewritten around Twitter infrastructure, so this article stays specific to the archived code that was inspected.

Distributed workers generating identifiers with a clock rollback risk cue

Combining time, worker identity, and a sequence

The original design combines a time value, a worker number, and a sequence number in an integer identifier. The time component supports approximate ordering; the worker component distinguishes generators operating concurrently; and the sequence lets one worker issue multiple IDs during the same time interval. Field widths, time units, and the chosen epoch are implementation choices. A library described as Snowflake may use a different layout or different operational assumptions, so the name alone does not identify a wire format.

The timestamp-based layout makes IDs roughly sortable by time, but values from different workers do not establish causality for near-simultaneous events. In this snowflake-2010 code, time is measured in milliseconds and the ID combines a 5-bit datacenter field, a 5-bit worker field, and a 12-bit sequence. the 12-bit sequence field represents 4,096 values per worker per millisecond. After those values are exhausted, the next request waits for time to advance. This is a capacity of the inspected code, not a throughput promise. If time is earlier than the last timestamp, the code throws InvalidSystemClock before changing the sequence. It also rejects worker or datacenter IDs outside their bit ranges; the deployment must still prevent two live nodes from sharing an ID.

Uniqueness depends on the whole deployment

For the common time–worker–sequence pattern, uniqueness depends on keeping the combination distinct. Two live generators should not share a worker identity while producing IDs in the same time range; one worker should not reuse a sequence value within a time interval; and the timestamp field must remain interpretable under the chosen epoch and unit. A bit diagram cannot prove these properties. Provisioning, configuration distribution, restart behavior, container relocation, and state recovery all influence whether the assumptions hold.

Clock rollback creates a separate edge case. If a worker has already emitted IDs using a later timestamp and its system clock moves backward, it may revisit a time value it used before. Whether that causes a collision depends on how the implementation handles the rollback, sequence state, and subsequent calls. A 2012 issue (#6) reported that a then-current code path could reset the sequence before handling a clock-regression error, potentially creating duplicates when a timestamp was revisited. The snowflake-2010 tagged source read here instead checks timestamp < lastTimestamp and throws before sequence handling. Do not generalize the issue report to that inspected tag or to every later variant; verify the exact version and commit deployed.

Tests that expose assumptions

Read the code and configuration for the exact version in use, then test the invariants the service relies on. Check whether worker identities can be assigned twice, what happens when a per-time sequence is exhausted, and whether rollback returns an error, waits, or risks reusing a prior timestamp. Include restarts, container moves, recovery after a crash, time-unit boundaries, and any change to the configured epoch. Also inspect what state remains after a failed call and whether callers can retry without creating a second business operation.

A single generator producing many IDs in a happy-path test is not enough. Add cases that deliberately assign the same worker identity to two processes, move a test clock backward and then forward, exhaust the sequence, and restart a generator while preserving or resetting state. A clock-error response alone does not prove that the next call is safe: confirm that the implementation’s retained watermark and sequence state prevent duplicate combinations. If uniqueness is business-critical, test the storage layer’s duplicate detection and the application’s recovery behavior as well.

Expert perspective: ordering is an application-level convenience

Discord Senior Staff Software Engineer Bo Ingram describes Snowflake identifiers as chronologically sortable in Discord’s message system. His production example combines channel-based partitioning with a fixed time bucket. It shows that sortable IDs are one input to a larger data layout, not a guarantee of absolute global ordering or a solution to every database problem.

The original Twitter repository is archived, and its README says the initial release was retired while the internal version was rewritten around Twitter infrastructure. Verify the exact deployed version’s worker assignment and rollback behavior; use a separate mechanism when a definitive causal order is required.

Sources

Twitter Archive: Snowflake source repository Bo Ingram, Senior Staff Software Engineer at Discord: How Discord Stores Trillions of Messages Twitter Archive Snowflake 2010: IdWorker.scala Twitter Archive Snowflake issue #6: Duplicate ids possible if clock moves backwards