System Design LabSystem Design QuestionsDesign Unique ID Generator

Design Unique ID Generator

EasyDistributed Systemsdistributedid-generationconcurrencyclock-sync

Question Overview

Design a service that hands out unique, roughly time-ordered 64-bit IDs to hundreds of machines without a central bottleneck. The interesting parts are the Snowflake-style bit layout, assigning worker IDs safely, and surviving clock skew without ever issuing a duplicate.…

Sign up to see the full question and AI interviewer

Requirements

  • Generate 64-bit numeric IDs that are unique across all instances and regions for the system's lifetime
  • IDs are roughly time-ordered (k-sorted): later IDs sort after earlier ones to within a few milliseconds
  • Generation happens in-process in under 1 ms, with no network call or central database on the hot path
  • Support batch requests of up to 1,000 IDs and decoding of the creation timestamp from any ID
  • Zero duplicates across process restarts, rolling deploys, and NTP clock adjustments
  • Keep generating IDs while the coordination service is down, for 99.99% availability

Back-of-the-envelope numbers

  • Timestamp range: 2^41 ms ≈ 2.2 × 10^12 ms ÷ (1,000 × 86,400 × 365) ≈ 69.7 years from a custom epoch
  • Per-instance ceiling: 12-bit sequence = 4,096 IDs per millisecond per worker ≈ 4.1M IDs/s on one instance
  • Per-instance demand: 1M IDs/s peak ÷ 400 instances = 2,500 IDs/s ≈ 2.5 IDs per ms, far below the 4,096/ms ceiling
  • Worker IDs: 10 bits = 1,024 values for 400 instances, leaving room for rolling deploys where old and new instances overlap
  • Daily volume: 200K IDs/s × 86,400 s ≈ 17.3B IDs/day; 63 usable bits allow 2^63 ≈ 9.2 × 10^18 values
  • Index savings: 8-byte IDs instead of 16-byte UUIDs save 8 B × 17.3B ≈ 138 GB/day on every index keyed by ID
  • Ticket-server alternative: leasing blocks of 10K IDs needs 1M IDs/s ÷ 10,000 = 100 block fetches/s from the ticket DB

Key components

  • Bit layout: 1 unused sign bit, 41-bit millisecond timestamp since a custom epoch, 10-bit worker ID, 12-bit per-millisecond sequence
  • Generator library embedded in each service: an atomic (last_ms, sequence) pair; when the sequence exhausts within a millisecond, wait for the next one
  • Worker ID leasing: each instance claims a free ID as an ephemeral node in ZooKeeper or etcd with a TTL and stops issuing if renewal fails
  • Clock guard: NTP in slew mode, persist the last issued timestamp, wait out small backward jumps and refuse to issue on large ones
  • Optional thin ID service over gRPC for clients that cannot embed the library, returning batches to amortize the network hop
  • Alternatives weighed: UUIDv4 (random, 128-bit, poor index locality), UUIDv7 (time-ordered, still 128-bit), DB auto-increment, ticket servers leasing ranges

Common mistakes

  • Ignoring backward clock jumps from NTP corrections, so a node reuses old timestamps and issues duplicate IDs
  • Deriving worker IDs from a hash of hostname or IP; with 400 instances in 1,024 slots, collisions are nearly certain
  • Claiming IDs are strictly increasing globally; across instances they are only k-sorted, and order within a millisecond is arbitrary
  • Putting a central network service or database sequence on every request, adding latency and a single point of failure
  • Returning 64-bit IDs as JSON numbers; JavaScript loses integer precision above 2^53, so also send them as strings
  • Using random UUIDv4 as a clustered primary key, causing random B-tree inserts, page splits, and poor cache locality
  • Forgetting that Snowflake-style IDs leak creation time and rough volume, which matters for public-facing identifiers

Likely follow-ups

  • How would your generator behave if NTP moved the clock backward by 5 seconds?
  • How would you change the bit layout to support 10,000 generator instances?
  • What happens if an instance pauses for a long GC, loses its worker ID lease, and then resumes?
  • How would you expose non-guessable public IDs while keeping internal IDs sortable?
  • How would you migrate when the 41-bit timestamp nears exhaustion without breaking existing IDs?
  • When would you choose UUIDv7 over a Snowflake-style 64-bit ID?

No community solutions yet

Be the first to publish your solution

Practice ‘Design Unique ID Generator’ with an AI Interviewer

Get scored feedback on your diagram, scalability approach, and trade-offs. Free while we grow — up to 3 full interviews a day.