System Design · Easy
Design a unique id generator
Generate globally unique, roughly sortable IDs at high throughput without a central bottleneck.
Requirements
What the system must do, and how well it must do it.
Functional
Generate 64-bit IDs that are unique across all nodes.
IDs should be roughly time-ordered (newer IDs > older IDs).
Support at least 10K IDs/second per node.
No single point of failure or coordination bottleneck.
Non-functional
ID generation latency under 100 µs at p99.
Tolerate clock drift up to a few milliseconds.
Node IDs assigned at startup, no central registry required.
IDs must be URL-safe when encoded (base62 or similar).
Estimation
Back of the envelope numbers that drive the design.
41-bit timestamp (ms since custom epoch) gives ~69 years.
10-bit node ID supports 1,024 nodes.
12-bit sequence gives 4,096 IDs/ms per node — 4M IDs/s per node.
Total throughput: billions of IDs/sec across the fleet.
Architecture
Design decisions
Bit layout
`` ┌───┬─────────────────────────┬─────────────┬──────────────┐ │ 0 │ 41 bits: timestamp (ms) │ 10 bits: │ 12 bits: │ │ │ since custom epoch │ node ID │ sequence │ └───┴─────────────────────────┴─────────────┴──────────────┘ `` The sign bit (bit 63) is always 0 so the ID stays positive in signed languages. The custom epoch (for example 2020-01-01) maximises the timestamp runway.
Clock drift handling
If the system clock moves backward, the generator must not emit duplicate IDs. Options: (1) wait until the clock catches up (blocks the thread), (2) return an error to the caller, (3) use a logical clock that only moves forward. The pragmatic choice is to wait up to a configurable threshold (for example 10 ms), then error. NTP keeps drift under a few ms in practice.
Node ID assignment
Assign node IDs from a coordination service (ZooKeeper, etcd, Consul) at startup, or derive them from the pod IP / instance ID modulo 1024. The assignment must be stable for the lifetime of the process. If a node restarts, it should get the same ID to avoid wasting the ID space.
Questions and answers
Follow-ups an interviewer is likely to ask. Try answering before you open each one.
What if you need more than 1,024 nodes?
Steal bits from the sequence (for example 11 bits node, 11 bits sequence) or use a 128-bit ID (UUIDv7 style). The 64-bit layout is a sweet spot for most systems; only planet-scale systems need more.
How do you encode the ID for URLs?
Base62 (0-9, a-z, A-Z) is URL-safe and gives 11 characters for 64 bits. Avoid base64 because + and / need escaping. Crockford base32 is another option — slightly longer but case-insensitive and avoids ambiguous characters.
Can you generate IDs in a serverless function?
Yes, but you must solve node ID assignment. Use a deterministic hash of the function name + region + instance ID, or allocate a block of node IDs per deployment. The sequence counter must be in-memory (not shared) because cold starts reset it.