Design a distributed unique ID generator (Snowflake)
A single database counter does not scale across servers. Learn UUIDs, Snowflake-style 64-bit IDs and the clock traps.

Goal: create IDs that are unique across many servers, generated fast without coordination, and ideally sortable by time.
Why not a database auto-increment
- A single counter is a bottleneck and a single point of failure.
- With sharded databases, each shard would generate overlapping numbers.
- Sequential IDs expose how many records you have and are easy to guess.
Option 1: UUID
A 128-bit random identifier (UUIDv4). Any server can create one with a negligible chance of collision.
- Pros: no coordination at all.
- Cons: 16 bytes, not sortable by time. Random keys hurt database index locality, so inserts into a B-tree are slower and the index is bigger.
Option 2: time-ordered IDs (UUIDv7, ULID)
They put a timestamp at the start and random bits after it. IDs sort roughly by creation time, which keeps indexes friendly, and there is still no coordination.
Option 3: Snowflake-style 64-bit ID
Popularised by Twitter. A 64-bit integer built from parts:
| Part | Bits | Meaning |
|---|---|---|
| Sign | 1 | always 0 |
| Timestamp | 41 | milliseconds since a custom start date (about 69 years) |
| Machine ID | 10 | which worker made it (up to 1,024) |
| Sequence | 12 | counter within the same millisecond (4,096 per ms per machine) |
Each machine can make about 4 million IDs a second. IDs are unique (different machine bits), sortable by time, and fit in a normal 64-bit integer column.
Problems to handle
- Machine ID assignment: give each worker a unique ID, from a coordination service (ZooKeeper/etcd) or configuration.
- Clock going backwards: NTP corrections can move time back and create duplicates. Detect it and wait, or refuse to generate until the clock catches up.
- Sequence overflow: if more than 4,096 IDs are needed in one millisecond, wait for the next millisecond.
- Clock skew across machines only affects exact ordering, not uniqueness.
Other approach: ticket servers
A dedicated service hands out blocks of numbers to app servers, which then assign them locally. Simple, but the service must be highly available.
Which to choose
| Need | Choice |
|---|---|
| Simplest, no coordination | UUIDv4 (or UUIDv7 for better indexes) |
| Compact 64-bit, sortable | Snowflake-style |
| Strictly ordered, single database | Sequence |
Takeaway: use a time-ordered ID. UUIDv7 for simplicity, or Snowflake when you need compact 64-bit IDs, and guard against clocks that move backwards.
System Design series, Part 4 (designing the infrastructure): 1 of 4.


