SD System Design In Depth
0%
lesson system-designidentifiersclocks

Snowflake ID design

Module 2.2: NoSQL Architectures, Partitioning & IDs Updated Sep 17, 2026
📄 Cheat Sheet
System Design - Part 12 | Design a Unique ID Generator | 4 Methods
Nikhil Lohia System Design - Part 12 | Design a Unique ID Generator | 4 Methods Watch on YouTube ↗

Builds up to the Snowflake layout and explains the timestamp, datacenter/worker and sequence fields and their limits in a design-interview flow; no better-produced dedicated Snowflake video was found.

0:00 / --:--

Concrete scenario

Several workers generate sortable IDs concurrently, then one virtual machine resumes with an older clock and a reused worker ID.

Mechanics

Pack a custom-epoch timestamp, unique worker ID, and per-tick sequence into an integer. Concurrent callers need an atomic counter, lock, or single-threaded owner; worker IDs need leases or durable assignment. On rollback, wait with a bound, change an epoch/worker component, or fail safely according to the contract.

Failure mode

Clock rollback plus worker-ID reuse can duplicate IDs. Sequence exhaustion blocks until a later tick, and restarting without preserving assignment can overlap another generator.

Trade-off

Snowflake-style IDs are compact and roughly time ordered, but depend on clock and worker management. UUIDv4 avoids those dependencies; UUIDv7 offers time locality with a larger representation.

Worked example: the numbers behind the 64 bits

FieldBitsCapacityDesign note
Sign1Always 0Keeps IDs positive in signed BIGINT and Java long
Timestamp (ms since custom epoch)412^41 ms, about 69.7 yearsTwitter epoch 1288834974657 (Nov 2010)
Worker ID (datacenter 5 + machine 5)101,024 generatorsMust be unique among live generators
Sequence124,096 per ms per workerResets each millisecond

Throughput: 4,096 per ms is 4.096M IDs/s per worker, and 1,024 workers give about 4.2B IDs/s cluster-wide. If a worker exhausts 4,096 in one millisecond, it spins until the next millisecond.

Tuning the split: if you only ever need 64 workers but bursts of 50k IDs/ms, use 6 worker bits and 16 sequence bits. Sonyflake uses 39 bits of 10 ms units (about 174 years), 8-bit sequence and 16-bit machine ID, trading per-ms throughput for lifespan and more machines. Instagram uses 41 bits of time, 13 bits of logical shard ID and 10 bits of per-shard sequence, generated inside Postgres.

Generator logic

flowchart TD A["next_id called"] --> B["now = current ms"] B --> C{"now less than last_ts?"} C -->|"Yes, small gap"| D["Wait until now reaches last_ts"] C -->|"Yes, large gap"| E["Refuse: raise error and alert"] C -->|"No"| F{"now equals last_ts?"} F -->|"Yes"| G["seq = seq + 1"] G --> H{"seq overflow?"} H -->|"Yes"| I["Spin to next ms, seq = 0"] H -->|"No"| J["Compose id"] F -->|"No"| K["seq = 0"] K --> J D --> B I --> J J --> L["last_ts = now, return id"]

Failure modes and defences

  • Clock rollback: keep last_ts in memory, wait out small regressions (a few ms), and refuse on large ones. Persisting a high-water mark periodically (for example, every second) defends against restarts with a bad clock. Configure NTP (chrony) to slew rather than step.
  • Worker ID reuse: two processes with the same worker ID in the same ms will collide. Use leases with fencing: a process that loses its lease must stop issuing IDs before the lease can be reassigned.
  • Multi-threading: the (last_ts, seq) pair must update atomically, using a mutex or a CAS on a packed 64-bit state.
  • Ordering is only k-sorted: IDs from different workers interleave within clock skew, so do not use them for strict global ordering.
Check yourself Question 1 of 3
Thread-safe generator recall
From: Mechanics

A Snowflake generator runs in a multi-threaded service. What must be true of its (last_ts, sequence) state?

Snowflake ID: 1 + 41 + 10 + 12 bits

A Snowflake ID packs a sign bit (always 0), 41 bits of milliseconds since a custom epoch, a 10-bit worker ID and a 12-bit per-millisecond sequence into one signed 64-bit integer. IDs from one worker are strictly increasing, and IDs from all workers sort roughly by time.

Paste an ID (or click one in the log) to decode it with the current epoch.
Event log (click an ID to decode it)

Key Takeaways

Snowflake IDs require unique worker assignment and synchronized sequence generation.
Clock rollback and worker reuse can cause collisions.
Compact ordering comes with clock and lifecycle dependencies.
Was this lesson helpful? Spot an issue or have a suggestion? Let us know on GitHub.
Report an issue