Illustration: UUID v4 Collisions: A Disaster That Effectively Never Happens

Every developer who adopts UUIDs eventually asks the nervous question: what if two of them collide? It is a fair worry — a collided primary key sounds catastrophic — but the honest answer is that a version-4 UUID collision is so improbable that you will never debug one. The disasters that do happen come from somewhere else entirely. Here is the arithmetic, and then the actual failure mode.

How much randomness is in a v4 UUID?

A UUID is 128 bits, but not all of them are random. In version 4, six bits are fixed to declare the version and variant — you can spot them as the 4 that opens the third group and the 8, 9, a or b that opens the fourth. That leaves 122 random bits: about 5.3 × 10³⁶ possible values. Numbers that large defeat intuition, so reach for the standard yardstick of improbability: you are vastly more likely to win a national lottery twice in a row than to witness a specific pair of UUIDs collide.

The birthday paradox, applied honestly

The legitimate subtlety is the birthday paradox: collisions become plausible not when you compare one pair, but when you generate so many values that any pair among them might match. For 122 random bits, you would need to generate roughly 2⁶¹ UUIDs — about 2.3 billion billions — before the chance of a single collision anywhere in the set reached 50%. At a billion UUIDs per second, sustained, that is over seventy years of generation. Realistic systems mint millions, perhaps billions, of IDs in their entire lifetime. A billion UUIDs carries a collision probability in the neighbourhood of one in 10¹⁹ — smaller than the chance that a hardware bit-flip corrupts the ID first.

So why do duplicate UUIDs exist in the wild?

When a real system reports a "UUID collision", the post-mortem almost never blames probability. It blames the random source: a generator seeded with the current time, a virtual machine cloned after its entropy pool was captured, Math.random pressed into service where a cryptographic source was required, or — most mundanely — a copy-paste bug, a replayed request, a fixture reused in production. The mathematics held; the randomness did not. That is why it matters that generators draw from crypto.getRandomValues or an equivalent OS-level source rather than a fast, predictable pseudo-random function.

What about the other versions?

Version 4 is the one built on pure randomness, but it has siblings worth knowing before you standardise. Version 1 UUIDs embed the current time and the generating machine's MAC address — orderly and unique, but they leak when and roughly where an ID was minted, which is why they have fallen out of favour for anything public. The newer version 7 keeps a timestamp up front, so IDs sort by creation time (kind to database indexes), while filling the remaining bits with randomness; its collision behaviour rests on the same arithmetic as v4 for practical volumes. None of these versions changes the conclusion: with a proper random source, the bits do their job. The failures live in the plumbing, not the format.

The practical takeaway

Use v4 UUIDs for primary keys, idempotency keys and distributed minting without a coordinating server, and spend your worry budget elsewhere: on backups, on retries, on the human systems around the IDs. If uniqueness must survive even theoretical doubt — say, in a payment ledger — the answer is a database uniqueness constraint that rejects a duplicate, not a longer ID. Constraints catch every cause of duplication, including the boring ones that actually happen.

Try the tool behind this article: UUID Generator runs entirely in your browser — nothing you paste is uploaded.

← All blog articles