Free preview

Approach 1: UUIDs

In one line: UUIDs are the reflexive answer, and they are genuinely excellent at the hard part — coordination. Understanding precisely which requirements they fail is what lets you defend using them, or not.

How it works

Each server produces IDs on its own. An example UUID:

123e4567e89b12d3a456426614174000

This approach is scalable, highly available, and has a low collision probability — and it achieves all three by never talking to anything.

The five drawbacks

DrawbackDetail
Performance128-bit non-numeric keys slow down primary key indexing and inserts
SizeThey exceed the 64-bit size limit — twice over
FormatNon-numeric strings are unsuitable for some use cases
UniquenessThere is a small chance of duplication — minimal, but UUIDs are not deterministically unique
OrderingIDs are not monotonically increasing — no time-sortability at all

The performance point is the one that bites in practice

Random 128-bit keys are the worst case for a B-tree index. Because they are random, consecutive inserts land in random pages — so the index cannot keep recent writes together, page splits are frequent, and cache locality is destroyed.

A monotonically increasing key appends to the same hot page; a random key touches the whole tree. On a large table that difference is dramatic, and it is why "just use UUIDs" hurts most at exactly the scale where you needed a sequencer in the first place.

The neighbouring idea: hash something you already have

A related instinct is to hash an input — the content, the long URL, the user plus timestamp — and truncate the digest to the length you need.

It is attractive because it is deterministic and needs no coordination: the same input always produces the same identifier, which doubles as free deduplication. And it fails for a reason worth being precise about.

Truncating a hash to a short code reintroduces collisions, and unlike a UUID's 128 bits the probability is no longer negligible — a six-character base62 code is about 56 billion values, which the birthday bound makes contested well before you exhaust it. So a hash-based scheme needs a collision check on write: look up the candidate, and on a hit re-hash with a salt and try again.

That check is the thing to notice, because it quietly reinstates exactly what hashing was supposed to avoid. You are now doing a read before every write against a shared store, which is the coordination the approach existed to escape — and under contention the retry loop gets worse as the space fills.

The rule this leaves you with: hash when determinism or deduplication is the point, count when uniqueness is the point. If you need the same input to yield the same ID, pay for the collision check knowingly; if you only need distinct IDs, a counter gives you that without ever looking anything up.

The modern answer: put the time at the front

The two objections above — not sortable, and terrible for a B-tree index — are both consequences of one choice: the random bits are at the front. A key that starts random scatters across the index and sorts arbitrarily.

That is fixable without giving up the thing UUIDs are good at.

UUID v7 leads with a 48-bit UNIX millisecond timestamp and fills the remainder with randomness. Sorting the string sorts by creation time; inserts append near the end of the index instead of scattering. ULID and KSUID are the same idea with different encodings — a timestamp prefix followed by entropy.

This matters for the chapter's argument, because it is the first approach that gets sortability without coordination:

UUID v4UUID v7 / ULIDSnowflake
Coordination neededNoneNoneWorker IDs must be assigned
Time-sortableYes
Index localityTerribleGoodGood
Size128 bits128 bits64 bits
UniquenessProbabilisticProbabilistic within a millisecondDeterministic
Survives a partitionYesOnly if it already has a worker ID

So it removes two of the five drawbacks and leaves the other three. It is still 128 bits, which fails a 64-bit requirement outright, and uniqueness is still probabilistic — though now only among IDs generated in the same millisecond, which is a much smaller birthday problem than across all time. And a timestamp prefix means the ID reveals when the row was created, which the fully random version did not.

The honest positioning for an interview: if the 64-bit constraint is real, UUID v7 does not save you and Snowflake is the answer. If the constraint is soft — and outside an interview it very often is — UUID v7 is frequently the better engineering choice, because it buys sortability and index locality while keeping the property that actually matters operationally: a partitioned server can still mint valid IDs with no one to ask.

Naming it is worth doing even in a chapter that goes on to build Snowflake, because an interviewer who has adopted it will notice its absence.

Scorecard

UniqueScalableAvailable64-bit numeric ID
Using UUID

Two out of four. Scalability and availability are perfect precisely because there is no coordination — and uniqueness and size are exactly what that freedom costs.

Key takeaway

UUIDs trade size and determinism for zero coordination. Against a 64-bit numeric requirement they are disqualified on arithmetic alone — but note why they are attractive, because the next two approaches give up availability to fix it. And two of the five drawbacks are self-inflicted: UUID v7 puts the timestamp first, which restores sortability and index locality while keeping the coordination-free property. It is still 128 bits, so the 64-bit constraint is what actually forces you onward.

Interview signal by level

LevelWhat a strong answer sounds like
L4"Use UUIDs — they're unique."
L5Knows the limits: "UUIDs need no coordination, but they're 128 bits and not sortable, so they fail a 64-bit numeric requirement."
Staff+Names both sides precisely: "probabilistic rather than deterministic uniqueness, and random keys are the worst case for B-tree locality — consecutive inserts scatter across the index. But zero coordination means a partitioned server still generates valid IDs, which is a real availability property the alternatives give up."

Next: buying uniqueness by adding a coordinator.

Enjoying the preview?

Create a free account to unlock the rest of this course, the in-browser judge, and live AI mock interviews.

Sign up free to continue