Why UUIDs Basically Never Collide (Even Without Checking)
Systems generate random UUIDs constantly with no central coordination and no duplicate check, and it works. The birthday paradox explains why that is actually a reasonable bet.
· 3 min read
A surprising amount of trust placed in a random number
A standard random UUID is generated independently, by any number of completely uncoordinated systems, with no central authority handing out the next available identifier and no check against any existing list of identifiers already in use — and despite that, collisions are, for all practical purposes, something that never happens. That is a genuinely bold claim resting entirely on probability rather than coordination, and understanding why it holds up requires the same piece of counterintuitive mathematics that explains a much more famous puzzle: how few people need to be in a room before two of them are likely to share a birthday.
The birthday paradox, briefly
The classical birthday paradox asks how many people need to be gathered in a room before there is a better-than-even chance that two of them share a birthday, and the answer — just 23 people, against 365 possible birthdays — surprises most people, who intuitively expect the number to be much closer to 365 itself. The reason the true answer is so much smaller is that the relevant comparison is not "does any specific person share my birthday" but "does any pair, out of all the possible pairs in the room, share a birthday" — and the number of possible pairs grows far faster than the number of people does, since with 23 people there are already 253 distinct pairs, each one an independent opportunity for a match. This exact mathematical pattern — the number of comparison opportunities growing quadratically while the number of items grows only linearly — is called the birthday problem, and it applies directly to any situation involving random values drawn from a fixed space and checked for duplicates, UUIDs very much included.
Applying the same math to a 128-bit random identifier
A standard random UUID (version 4) draws from a space of 122 genuinely random bits — a handful of the 128 total bits are fixed by the format specification itself to identify the version — which means the total number of possible values is 2 to the power of 122, an almost incomprehensibly large number. Applying the same birthday-paradox reasoning used for the 365-day example, but scaled up to that vastly larger space, gives the point at which a collision becomes likely: roughly 2.7 quintillion UUIDs would need to be generated before the probability of any two colliding rises to somewhere around 50 percent — for scale, that is more UUIDs than there are estimated grains of sand on every beach on Earth. A single system, or even a large number of systems combined, generating UUIDs at any realistic real-world rate would take a length of time vastly exceeding the age of the universe to approach that threshold, which is the actual mathematical basis for treating UUID collisions as something that does not need to be checked for in practice.
Why v7 changes the ordering property without touching this math at all
UUID version 7, standardised more recently specifically to produce identifiers that sort in roughly chronological order, achieves that by placing a millisecond-precision timestamp in the identifier's leading bits rather than filling the entire value with random data the way version 4 does. This might sound like it would weaken the collision-resistance guarantee, since part of the value is now predictable rather than random — but the remaining bits are still filled with the same amount of genuinely random data as before, and because two UUIDs generated in the very same millisecond still need their random remainder to happen to match exactly, the practical collision resistance stays comparable to version 4's for any realistic generation rate. What v7 actually changes is a different, unrelated property — sort order — not the collision math discussed here at all, and the two are worth keeping conceptually separate: uniqueness comes from the sheer size of the random space, while sortability comes from where the timestamp sits within the value.
What this trust in raw probability actually buys
Because the collision probability is genuinely, not just casually, negligible, systems can generate unique identifiers completely independently — a mobile app working offline with no network connection, a serverless function that spins up and vanishes in milliseconds, a thousand parallel microservice instances running simultaneously — with zero coordination between them and no central registry keeping track of what has already been issued, and still have a mathematically sound expectation that no two of those identifiers will ever collide. That is precisely the property a centrally issued, sequential identifier could never offer without a shared coordinating authority slowing everything down, and it is the entire reason random UUIDs became the default choice for distributed systems that need identifiers no coordination step could otherwise keep up with.