Quick answer
For random UUID v4 values, you would need to make about 2.7 quintillion (2.7 × 10^18) of them before there is even a 50% chance that any two match. At a billion UUIDs per second, that takes about 86 years. In practice, duplicates come from bugs and bad random number generators, not from bad luck.
Where the randomness lives
A UUID is 128 bits. In version 4, six of those bits are fixed: four say “this is version 4” and two mark the standard layout, called the variant. The other 122 bits are random.
- Random
- Version, always 4
- Variant, 8, 9, a or b
122 random bits gives about 5.3 × 10^36 possible values. That is 5.3 undecillion, a number with 37 digits. If your new UUID had to match one specific existing UUID, the chance would be 1 in that number, which is effectively zero.
Why it is not 1 in 2^122
The real question is different. You do not care whether a new ID matches one particular ID. You care whether any two IDs, out of all the IDs you have ever made, match.
This is the birthday problem. In a room of just 23 people, there is a better than even chance that two share a birthday, even though there are 365 days. That is because there are 253 pairs of people, and each pair is a chance for a match.
The same thing happens with UUIDs. The number of pairs grows much faster than the number of IDs. The rule of thumb is that collisions become likely once you have made roughly the square root of the number of possible values. For 122 bits, the square root is about 2^61, which is around 2.3 quintillion. That is where the 50% figure of 2.7 quintillion comes from.
The odds in numbers
These are the chances that at least one pair matches, for random UUID v4 values from a good generator:
| UUIDs made in total | Chance of any duplicate |
|---|---|
| 1 billion (10^9) | about 1 in 10 quintillion |
| 1 trillion (10^12) | about 1 in 10 trillion |
| 103 trillion | about 1 in a billion |
| 1 quadrillion (10^15) | about 1 in 10 million |
| 327 quadrillion | about 1 in 100 |
| 2.7 quintillion | about 1 in 2 |
To put the last row in context, storing 2.7 quintillion UUIDs at 16 bytes each would take about 43 exabytes, just for the IDs. Few systems will ever come close.
Check it yourself
If you want to work out your own case, this approximation is accurate for any realistic number of IDs:
- Take the number of IDs and square it
(10^12)^2 = 10^24 - Divide by 2 × 2^122, which is about 1.06 × 10^37
10^24 / 1.06e37 ≈ 9.4e-14 - While the result is small, that is your chance of a duplicate
about 1 in 10.6 trillion
Other versions
UUID v7 puts a millisecond timestamp first and up to 74 random bits after it. Two IDs can only clash if they were made in the same millisecond, so the question becomes how many you make per millisecond. A busy system making thousands of IDs every millisecond is still nowhere near a clash. Many libraries also use a counter within a millisecond, which removes clashes from a single generator entirely.
UUID v1 and v6 use the time, a clock sequence and a node ID instead of randomness. They are unique as long as those parts are set up correctly on each machine.
UUID v3 and v5 are built from a hash of a name. The same name always gives the same UUID. That is the point of them, not a collision.
Nano ID has 126 random bits by default, a little more than v4, so the odds are similar. Shorter Nano IDs have far fewer bits and collide far sooner.
What really causes duplicates
When teams do see duplicate UUIDs, the cause is almost always one of these:
- A weak random source. Some old or home-made generators use a non-secure function such as JavaScript’s
Math.random(). Its output can repeat or be predicted. Usecrypto.randomUUID()in JavaScript,uuid.uuid4()in Python, or your database’s built-in function. - Copied random state. A virtual machine restored from a snapshot, or a process forked after its random generator was seeded, can produce the same sequence twice.
- Shortened IDs. Keeping only the first 8 characters leaves 32 bits, and a clash becomes likely after tens of thousands of IDs.
- Plain bugs. The same ID reused by a retry, a test fixture copied into production, or a default value that was set once instead of per row.
Good to know
Keep the unique constraint
The odds are tiny, but a primary key or unique index costs nothing extra and catches the bugs above.
Never trim a UUID
Every character you drop removes 4 bits. If you need short IDs, use a Nano ID with enough length rather than cutting a UUID.
Unique is not the same as secret
A random UUID is hard to guess, but it is not a password. Do not rely on an ID alone to protect private data.

