gg
Home › Blog › Why a random UUID is safe to assume unique

Why a random UUID is safe to assume unique

2026-08-28 · 4 min read
mathwebsecurityabout

A version-4 UUID is 128 bits printed as 32 hexadecimal characters in an 8-4-4-4-12 pattern. Six of those bits are fixed — four marking the version and two the variant — which leaves 122 bits chosen at random. Nothing else. There is no central registry, no counter, no coordination, and no lookup to see whether the value has been handed out before.

That is a strange arrangement. Two servers on opposite sides of the world, which have never exchanged a packet, each invent an identifier and both proceed as though it is theirs alone. The reason that works is not clever engineering. It is that 122 bits is a very large number of possibilities and the arithmetic of collisions, once you run it, comes out on your side.

The arithmetic, run properly

The question is not "what are the odds two particular identifiers match" — that one is easy and unhelpful, 1 in 2^122. The useful question is the birthday question: across a whole collection, what are the chances that some pair matches? That grows much faster, because a collection of k items contains k × (k − 1) ÷ 2 pairs, and the pair count grows with the square of k.

With N equally likely values, the chance of at least one collision among k draws is close to 1 − e^(−k × k ÷ 2N). Setting that to one half and solving gives the count at which a collision becomes an even bet: k = the square root of (2N × ln 2), which is about 1.1774 × the square root of N.

For a v4 UUID, N = 2^122, so the square root of N is 2^61, about 2.31 × 10^18. Multiply by 1.1774 and the even-money point is roughly 2.7 × 10^18 identifiers — about 2.7 billion billion of them. Generate a billion UUIDs a second and you would reach that point after something on the order of eighty years of continuous generation.

So the honest description is this: the collision probability is negligible, not zero. It is a bet, on numbers so large that in any real system the bet wins. Systems are built on it every day, deliberately, because the alternative — a central authority handing out identifiers — costs a round trip and a single point of failure, and that price is far higher than the risk being accepted.

Two things that quietly break the arithmetic

Every figure above assumes the 122 bits really are drawn from 2^122 equally likely possibilities. Two things break that assumption in practice, and both are about the source rather than the format.

A weak or repeated source. If two machines start their generators from the same starting value, they produce the same identifiers — not by improbable coincidence but by construction. This is a real failure mode: containers cloned from one image, virtual machines restored from a snapshot, embedded devices booting with an identical state.

A ceiling below 122 bits. An identifier can only be as unpredictable as the material behind it. If a generator's whole output descends from a 64-bit starting value, the honest figure is 64 bits, whatever the 32 printed characters suggest.

Which is exactly the case here

That second point applies to this tool, so here is the number. Each time you press Generate, the page draws one fresh 64-bit seed from the browser's cryptographic source and the whole batch of UUIDs follows from it. So the honest ceiling for this tool is 64 bits, not 122.

Run the same arithmetic on that: N = 2^64, the square root is 2^32 = 4,294,967,296, and multiplying by 1.1774 puts the even-money point near 5.06 × 10^9 generated batches. Closer in: at a billion batches, k × k ÷ 2N works out to about 0.0271, so the chance of any collision is roughly 2.7%. Small, and enormously smaller than the risk you would run with a careless source — but it is not the 122-bit figure, and pretending otherwise would be exactly the error this page is about.

Practically: use this tool for test fixtures, sample data, local correlation IDs and anything you are pasting into a scratch file. For identifiers your production system depends on, use the platform's own facility — crypto.randomUUID in a browser or Node, a maintained UUID library, or your database's own generator — all of which draw from the operating system's cryptographic source directly and give you the full 122 bits.

And whichever source you use, a UUID is an identifier, not a secret. It is not a permission, and a value that is hard to guess is still not an authorisation check.

The tool

The UUID v4 generator produces up to 50 at a time, one per line, with the version and variant bits set correctly, entirely on your device.

Try it free — with the steps shown

The UUID v4 runs in your browser and shows exactly how it got the answer, so the method sticks.

Open UUID v4

More from the blog