Unique ID Generation

Intermediate · 13 min read · High-Level Design, Distributed Systems Theory

UUIDs, ticket servers, Snowflake IDs and ULID/UUIDv7.

Every tweet, order, message and payment needs an identifier. On a single database, AUTO_INCREMENT solves it. Once writes are spread across many shards, services and regions, you need IDs that are unique without coordination — and often you want more: sortable by time, compact, and not leaking business information.

Requirements to clarify

Option 1 — Database auto-increment

Multi-master variant: with N databases, each uses auto_increment_increment = N and a different offset (server 1 generates 1, 3, 5…; server 2 generates 2, 4, 6…). Works, but adding servers is awkward and IDs aren't time-ordered across servers.

Option 2 — UUID (v4)

128 random bits (122 of them random). Generate anywhere, no coordination.

Option 3 — Ticket server

A dedicated service (or a database with one auto-increment table) hands out IDs. Flickr ran two such MySQL servers, one issuing odd and one even numbers.

Option 4 — Snowflake-style IDs

Twitter's Snowflake (2010) packs a timestamp, a machine ID and a sequence into a 64-bit integer:

Option 5 — ULID and UUIDv7

Modern standards that combine UUID-style decentralisation with time ordering:

Comparison

Exposing IDs publicly

Sequential or time-based IDs leak information (creation time, volume) and allow enumeration (/invoices/1001, /invoices/1002). Options:

Interview questions

  • Why might random UUIDv4 primary keys hurt database performance, and what would you use instead?
  • What happens in a Snowflake generator if the system clock goes backwards?
  • How do you assign unique machine IDs to Snowflake generators in an auto-scaling environment?

Practice

Write your answer before opening the suggested one. If you mark it "Partly" or "Missed it", it comes back in your review deck.

Further reading

Key takeaways

  • Distributed ID generation must be unique without per-ID coordination; also consider size, sortability and guessability.
  • UUIDv4 is simple but large and index-unfriendly; ticket servers with range allocation give compact IDs cheaply.
  • Snowflake packs time, machine and sequence into 64 bits: sortable, fast, but needs machine IDs and clock care.
  • UUIDv7/ULID give time-sortable 128-bit IDs with no machine-ID management.
  • Don't expose sequential IDs as a security boundary; always authorise lookups.

Previous: Distributed Transactions · Next: Caching