UUID v4 Collision Probability
Understand UUID v4 collision probability: the birthday paradox math, real-world numbers, and why 122 random bits make collisions virtually impossible.
Detailed Explanation
UUID v4 collision probability is one of the most frequently asked questions about UUIDs. The short answer: collisions are so improbable that you are more likely to be struck by a meteorite than to generate two identical UUID v4 values in any real application.
The math behind it: UUID v4 has 122 random bits (128 bits minus 4 version bits and 2 variant bits), giving 2^122 = 5.316 x 10^36 possible values. The collision probability follows the birthday paradox formula:
P(collision) ≈ 1 - e^(-n² / (2 * 2^122))
Where n is the number of UUIDs generated.
Concrete numbers:
| UUIDs Generated | Collision Probability |
|---|---|
| 1 million | 1 in 5.3 x 10^24 |
| 1 billion | 1 in 5.3 x 10^18 |
| 1 trillion | 1 in 5.3 x 10^12 |
| 2.71 x 10^18 | 50% (birthday bound) |
| 1 quadrillion | 1 in 5.3 x 10^6 |
To reach a 50% collision probability, you would need approximately 2.71 x 10^18 (2.71 quintillion) UUIDs. For perspective, if every person on Earth generated 1 UUID per second, it would take about 11 years to reach this number.
Why collisions still get reported: When developers report UUID "collisions," the cause is almost always one of:
- Broken random number generator: Using
Math.random()instead ofcrypto.getRandomValues(). JavaScript'sMath.random()is not cryptographically secure and some implementations have short periods. - Copy-paste bugs: The same UUID was inadvertently duplicated in code or data.
- Database migration errors: UUIDs were accidentally reused during data import.
- VM cloning: Virtual machines cloned from snapshots may share the same random seed state, causing identical sequences.
Protecting against edge cases:
// WRONG: Uses Math.random(), can produce predictable sequences
function badUuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
const r = Math.random() * 16 | 0;
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
}
// RIGHT: Uses cryptographic randomness
function goodUuid() {
return crypto.randomUUID();
}
Database-level protection: Even though collisions are virtually impossible, always add a UNIQUE constraint on UUID columns. This provides a safety net at negligible performance cost and catches bugs in UUID generation logic.
Storage scale context: If you stored every UUID ever generated by every computer on Earth, the total would still be infinitesimally small compared to the 2^122 possible values. The UUID v4 space is, for all practical purposes, inexhaustible.
Use Case
Understanding collision probability is critical when designing distributed systems that generate UUIDs independently: it provides the mathematical guarantee that a UNIQUE constraint violation will never occur under normal operation.