SD System Design In Depth
0%
lesson system-designidentifierscorrectness

Distributed ID generation

Module 2.2: NoSQL Architectures, Partitioning & IDs Updated Sep 17, 2026
📄 Cheat Sheet
L15: Distributed System Design Example (Unique ID)
Distributed Systems Course L15: Distributed System Design Example (Unique ID) Watch on YouTube ↗

Chris Colohan reasons through the design space (central counter, range allocation, random IDs, time-based IDs) from first principles instead of jumping to Snowflake.

0:00 / --:--

The Distributed Identifier Challenge

In a single-instance relational database, generating unique primary keys is trivial via auto-incrementing sequences (e.g., PostgreSQL BIGSERIAL or MySQL AUTO_INCREMENT). However, in horizontally partitioned distributed architectures, generating unique IDs across dozens of database shards introduces severe architectural bottlenecks:

  • Single Point of Failure (SPOF): A centralized database generating auto-increments creates a throughput ceiling and a single point of failure.
  • Information Leakage: Monotonically incrementing sequential IDs (1, 2, 3...) expose sensitive business intelligence (competitors can monitor order ID changes to calculate daily revenue). Time-ordered IDs such as Snowflake and UUIDv7 also leak each record's creation timestamp.
  • Cross-Shard Uniqueness: When independent database shards insert records concurrently without central coordination, duplicate IDs will corrupt data.

Core Approaches to Distributed ID Generation

flowchart TD Req["ID Generation Request"] --> Approach{"Architecture Choice"} Approach -->|"Random 128-Bit"| UUID["UUID v4: No Coordination, High Index Fragmentation"] Approach -->|"Central Ticket Service"| Ticket["Flickr Ticket Servers: Central DB, one ID per REPLACE INTO round trip"] Approach -->|"Timed 64-Bit, coordination only for worker IDs"| Snowflake["Twitter Snowflake: 64-Bit Time-Ordered (ULID and UUIDv7 are 128-bit)"] Snowflake --> BitLayout["Bitwise Layout: 41-bit Time + 10-bit Node + 12-bit Sequence"]

Detailed Trade-offs of Generation Patterns

1. Multi-Master Increment with Offsets (MySQL Pattern)

If you have k database instances, instance 1 generates 1, 1+k, 1+2k, instance 2 generates 2, 2+k, 2+2k, etc. While simple, this does not scale dynamically when adding servers, nor does it guarantee time-ordering.

2. UUIDv4 (Universally Unique Identifier)

Generates 128-bit pseudo-random values. Generation requires zero network coordination (O(1) locally). However, UUIDv4 values are completely random, causing severe B-Tree Index Page Splitting and high storage overhead (16 bytes vs 8 bytes for BIGINT).

3. Time-Sorted 64-Bit IDs (Twitter Snowflake)

Encodes millisecond timestamps, physical node identifiers, and in-millisecond sequence numbers into a single 64-bit integer. It fits directly into standard BIGINT fields, requires zero network coordination during generation, and sorts naturally in B-Tree indexes.

Check yourself Question 1 of 3
What IDs leak recall
From: The Distributed Identifier Challenge

A product team switches public order IDs from auto-increment integers to Snowflake IDs to stop competitors estimating order volume. What do Snowflake IDs still reveal?

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

Auto-incrementing database sequences create bottlenecks and leak business metrics.
UUIDv4 allows decentralized generation but ruins B-tree index locality due to random page splitting.
Snowflake-style 64-bit time-sorted IDs provide optimal performance, B-tree locality, and 4M+ IDs/sec per node.
Was this lesson helpful? Spot an issue or have a suggestion? Let us know on GitHub.
Report an issue