# Unique ID generation

> Unique ID generation gives each record or event an identifier without accidentally assigning the same value to something else. In system design interviews, the important choices are where IDs are generated, how uniqueness survives failures, and whether IDs need to be short, sortable, or unpredictable.

Source: https://sysround.com/concepts/unique-id-generation
Updated: 2026-11-05


## How unique id generation works

Start with the requirements: uniqueness within which namespace, expected creation rate, number of regions, acceptable length, and ordering needs. A database primary key, a public short URL, and a trace ID can justify different generators. Uniqueness, chronological order, and secrecy are separate properties.

A database sequence or auto-increment column is a simple starting point. A shared allocator can also hand out disjoint ranges, such as 1–10,000 to worker A and 10,001–20,000 to worker B, reducing coordination per ID. Range allocation must survive allocator failover without reissuing ranges; crashes can leave gaps, and allocation order does not guarantee commit order.

A Snowflake-style generator packs a timestamp, worker ID, and sequence number into an integer. One common layout uses 1 unused sign bit, 41 timestamp bits in milliseconds since a custom epoch, 10 worker bits, and 12 sequence bits. That supports 1,024 worker identities and 4,096 IDs per worker per millisecond, with a timestamp lifetime of about 69.7 years.

Snowflake uniqueness depends on exclusive worker identities and never reusing the same timestamp-worker-sequence tuple. Serialize generation within each worker; when the sequence is exhausted, wait for the next millisecond. If the clock moves backward, wait, reject generation, or use a carefully designed logical-time policy. Restarts and worker-ID reassignment must also prevent tuple reuse, including stopping an old worker before its identity is reused.

UUIDs let services generate IDs locally without allocating worker identities. UUIDv4 uses random bits and offers probabilistic uniqueness when generated correctly; UUIDv7 adds a timestamp prefix for approximate time ordering. Neither gives a strict global event order, and both use 128 bits rather than the 64 bits common in Snowflake-style designs.

Base62 encodes an integer using 62 characters, typically digits plus uppercase and lowercase letters. It makes an existing ID compact; it does not create uniqueness or hide predictable values. Seven Base62 characters provide 62^7 possible codes, about 3.52 trillion, while a nonnegative 63-bit Snowflake ID can require 11 characters. Specify a fixed alphabet and case-sensitive lookup.

## Worked example: Choosing codes for a URL shortener

Suppose a URL shortener expects 10,000 new links per second at peak and wants codes no longer than seven characters. Seven Base62 characters provide about 3.52 trillion values, but a full Snowflake ID can require 11 characters, so that layout does not meet the length requirement. Start with a durable allocator that grants disjoint blocks of 100,000 integers to application instances. Each instance allocates locally and Base62-encodes the integer. At peak, a fully consumed block represents ten seconds of aggregate demand. Store code-to-URL mappings under a unique constraint, never reissue allocated blocks, and accept gaps after crashes. Sequential codes are enumerable; if unpredictability is required, choose random codes with atomic collision retries and assess the collision rate as occupancy grows.

## Trade-offs

- **Central simplicity versus distributed availability.** A shared sequence is easy to reason about but adds an allocation dependency, while range allocation or local generation reduces coordination at the cost of more failure-handling logic.
- **Deterministic versus probabilistic uniqueness.** Counters and Snowflake layouts avoid collisions only while their allocation invariants hold, whereas random IDs depend on sufficient entropy and an acceptable collision probability.
- **Time ordering versus clock dependence.** Timestamp-prefixed IDs improve approximate sorting but introduce clock-skew concerns and do not establish global causality or commit order.
- **Compactness versus exposure.** Sequential and timestamp-based IDs are compact but can reveal creation patterns and make enumeration easier, so they are not authorization tokens.
- **Index locality versus write concentration.** Increasing keys can improve B-tree locality, but range-partitioning by those keys can concentrate new writes on one partition.
- **Uniqueness versus retry identity.** Generating a fresh unique ID on every retry still creates duplicate logical operations unless the original event ID or idempotency key is reused.

## When to use it in a system design interview

- A URL shortener needs compact codes with an explicit collision policy and enough namespace capacity.
- Multiple writers or regions must create records without contacting one global database for every ID.
- An ingestion pipeline needs stable event identities so retries and replay can be deduplicated.
- The design needs roughly time-sortable keys, and you can explain why strict global ordering is unnecessary.
- Trace and span identifiers must be generated across services and propagated without a central allocation request.

## How to bring it up in the interview

- State the required properties before naming an algorithm: uniqueness scope, peak rate, length, predictability, and ordering. Interviewers often probe whether a plain database sequence would be sufficient.
- For Snowflake IDs, show the bit allocation and calculate worker count, per-worker burst capacity, and epoch lifetime. Explain what happens when any field runs out.
- Defend the failure path, not just the happy path: clock rollback, process restart, duplicate worker identities, and regional isolation. A worker lease is insufficient unless an expired worker is prevented from continuing to generate conflicting IDs.
- For short URLs, distinguish generating an integer and Base62-encoding it from generating random Base62 strings. Random codes need atomic insert-if-absent and collision retries; encoding alone does not resolve collisions.
- Separate identity from ordering and deduplication. Expect follow-up questions about retrying the same operation, sorting across regions, public-ID enumeration, and passing 64-bit IDs through JavaScript without losing precision.

## Common mistakes

- Calling Base62 a hashing algorithm, encryption scheme, or source of uniqueness.
- Using a timestamp alone as an ID, ignoring simultaneous requests and clock rollback.
- Claiming Snowflake IDs are globally chronological or safely reusing worker IDs without a restart and reassignment policy.
- Assuming random codes cannot collide, or checking for a collision before insertion instead of enforcing uniqueness atomically.
- Creating a new event ID on every retry and expecting downstream deduplication to recognize the original operation.

## Interview questions where it comes up

- [Design a URL shortener like Bitly](https://sysround.com/questions/design-url-shortener): Unique short-code generation requires choosing between encoded allocated IDs and random codes, with explicit capacity and collision handling.
- [Design a distributed tracing system](https://sysround.com/questions/design-distributed-tracing): Trace and span identity must remain unambiguous across independently generating services while propagated IDs preserve trace relationships.
- [Design Google Analytics](https://sysround.com/questions/design-google-analytics): Retry-safe event collection needs stable event IDs that distinguish redelivery from genuinely separate user actions.
- [Design a top K trending system](https://sysround.com/questions/design-top-k): Share-ID deduplication requires assigning identity to each logical share and preserving it across duplicate delivery and replay.

## FAQ

### What is a Snowflake ID, and how does it stay unique?

A Snowflake ID combines a timestamp, a worker identity, and a per-time-unit sequence number in one integer. Uniqueness requires workers to have exclusive identities and never repeat a timestamp-worker-sequence tuple. Clock rollback, restarts, and identity reassignment need explicit handling.

### Should I use Snowflake IDs or UUIDs?

Use UUIDs when independent local generation and avoiding worker-ID coordination matter more than compactness; UUIDv7 also provides approximate time ordering. Consider Snowflake-style IDs when compact 64-bit values matter and you can operate worker allocation and clock-failure policies safely. A database sequence may still be simpler if your writes already depend on one database.

### Does Base62 encoding guarantee a unique short URL?

Base62 preserves uniqueness when it encodes distinct integers with a consistent alphabet and canonical representation. It does not make colliding inputs unique or prevent someone from guessing neighboring codes. Random Base62 strings require a unique constraint and retry-on-collision logic.

## Related concepts

- [Clock skew and time in distributed systems](https://sysround.com/concepts/clock-skew)
- [Idempotency and idempotency keys](https://sysround.com/concepts/idempotency)
- [Database sharding](https://sysround.com/concepts/database-sharding)
- [Message ordering](https://sysround.com/concepts/message-ordering)


---
SysRound (https://sysround.com) is an AI practice tool for system design interviews: a voice or typed AI interviewer, a shared whiteboard, then feedback on every skill and a model answer. Its feedback is AI-generated and can be wrong.
