UUID v4 Collision Probability at Scale
2.71 quintillion UUIDs for a 50% collision. At 1 billion per second: 85 years. The math says you will never see one in your lifetime. The RNG bugs disagree — and they've been right.
Published: 2026-07-02 | jslet Research | 13 min read | Classification: Unrestricted
The Question Everyone Asks: How Many UUIDs Before a Collision?
Every engineer who has ever added a UUID column to a database has asked some version of this question. Usually it happens during a schema review, or after reading a Hacker News comment about how UUID v4 "only" has 122 random bits, or while staring at a PRIMARY KEY definition at 2 AM wondering if this is the decision that takes down production three years from now.
The question takes different forms — "how many UUIDs before collision," "UUID v4 collision probability at scale," "what are the odds two servers generate the same UUID" — but they all want the same thing: a number. A threshold below which you can stop worrying and above which you need a plan B.
Here is that number: 2.71 × 10¹⁸. That is 2.71 quintillion UUID v4 generations before you have a 50% chance of seeing at least one collision. At 1 billion UUIDs generated per second — a rate that would require a mid-size datacenter dedicated to nothing but UUID generation — you hit that threshold in roughly 85 years. At 1 million per second — a busy distributed system with hundreds of services — you hit it in about 85,000 years. At the rate a typical production Postgres database generates primary keys — maybe 10,000 per second at peak — you hit it in roughly 8.5 million years, which is longer than the genus Homo has existed.
But that is only half the answer. The other half — the half that actually matters — is that every documented UUID v4 collision in production has been caused not by the math failing but by the random number generator failing. And that failure mode does not care about your scale. It can happen on the first two UUIDs your system generates, and it has.
I built the UUID v4 collision probability estimator on this site to make the birthday paradox math visible — to let you enter any generation volume and watch the collision probability resolve in real time, from "effectively impossible" through "one in a million" to "50%." This article is about what those numbers mean at real distributed-system scales, why the UUID version you choose matters more than the collision probability, and where production collisions actually come from.
The Birthday Paradox, Applied to 122 Bits
The collision probability for UUID v4 is not linear. It follows the birthday paradox: in a room of 23 people, there is a 50% chance two share a birthday — not because 23 is close to 365, but because the number of pairs of people grows quadratically. The same math governs UUID collisions, just with a much larger space.
UUID v4 (RFC 9562, which obsoleted RFC 4122 in 2024) dedicates 122 of its 128 bits to randomness. The remaining 6 bits are structural: 4 bits for the version identifier (binary 0100 = version 4) and 2 bits for the variant (binary 10). This leaves a total identifier space of 2¹²² ≈ 5.3 × 10³⁶ possible values. For context, that is roughly 10 billion times the estimated number of stars in the observable universe.
The birthday paradox formula for collision probability, when n is much smaller than the space size d, is approximated by:
p ≈ n² / (2d)
where n = number of UUIDs generated, d = 2¹²² ≈ 5.3 × 10³⁶
The n² term is what matters. Doubling the number of UUIDs quadruples the collision probability — but starting from a probability so astronomically small that even a billion-fold increase leaves you in "effectively never" territory. Here is the probability mapped across realistic generation volumes:
| UUIDs Generated | n² / (2 × 2¹²²) | Collision Probability | Interpretation |
|---|---|---|---|
| 1 million (10⁶) | 10¹² / 1.06×10³⁷ | ~10⁻²⁵ | Effectively impossible — less than winning Powerball 3 times in a row |
| 1 billion (10⁹) | 10¹⁸ / 1.06×10³⁷ | ~10⁻¹⁹ | Still effectively impossible at any realistic lifetime scale |
| 1 trillion (10¹²) | 10²⁴ / 1.06×10³⁷ | ~10⁻¹³ | Astronomically unlikely — 1 in 10 trillion |
| 1 quadrillion (10¹⁵) | 10³⁰ / 1.06×10³⁷ | ~10⁻⁷ | 1 in 10 million — approaching the territory where you might consider a check |
| 103 trillion (1.03×10¹⁴) | ~10⁻⁹ | 1 in 1 billion | Safe threshold — the probability most systems treat as "acceptable risk" |
| 3.26 × 10¹⁷ | ~0.01 | ~1% | 1% collision probability threshold |
| 2.71 × 10¹⁸ | ~1.0 | ~50% | 50% collision threshold — the √(2d) point of the birthday paradox |
The exact formula — which the estimator uses — accounts for the full birthday problem rather than the n²/2d approximation. The exact probability that at least two UUIDs collide among n randomly generated values from a space of size d is:
p = 1 − ∏k=1n−1 (1 − k/d)
For n ≪ d, this is well approximated by p ≈ 1 − e−n²/(2d)
The approximation p ≈ n²/2d — which is what the first two terms of the Taylor expansion give you — is accurate to within 1% for n up to about 10¹⁸. Beyond that, the exponential form takes over and the probability climbs toward 1. But "beyond that" means generating more than a quintillion UUIDs, which, as we will see, is not a number any single system approaches.
🔑 The Core Insight
UUID v4 collisions from randomness alone are a heat-death-of-the-universe problem, not an operational-risk problem.
At 1 billion UUIDs per second — a rate no production system sustains — you need 85 years for a 50% collision probability. The universe is 13.8 billion years old. You will be retired, dead, and your grandchildren will be dead before your system generates enough UUID v4 values for the math to matter. The collision you should actually worry about is the one caused by a bad RNG seed — and that can happen on the first two UUIDs your application generates.
What "At Scale" Actually Means
"Scale" is the most abused word in UUID collision discussions. People say "at scale" and mean anything from a single Postgres instance to a global fleet of millions of devices. The collision math does not care about your architecture diagram — it cares about one number: the total count of UUIDs generated from the same random space. Let's put that number in context for real systems.
How Many UUIDs Do Real Systems Generate?
To think clearly about collision risk, you need to know your generation rate — not your request rate, not your row count, not your database size. UUIDs are generated when you insert a row with a UUID primary key, when you create an idempotency key, when you assign a trace ID to a request, when you tag a log line with a correlation ID. These are different workloads with different rates, and they usually share the same entropy pool.
| System Profile | UUIDs Generated / Second | UUIDs / Year | Years to 50% Collision | Years to 10⁻⁹ Risk |
|---|---|---|---|---|
| Single Postgres instance (PK gen) | ~10,000 | 3.15 × 10¹¹ | 8.6 million years | 3,270 years |
| Large SaaS (100 services, trace IDs + PKs) | ~1,000,000 | 3.15 × 10¹³ | 86,000 years | 32.7 years |
| Global CDN (per-request trace IDs) | ~10,000,000 | 3.15 × 10¹⁴ | 8,600 years | 3.3 years |
| IoT fleet (1B devices, 1 UUID/day each) | ~11,574 | 3.65 × 10¹¹ | 7.4 million years | 2,820 years |
| Entire Amazon retail platform (all ops as UUIDs) | ~10¹² / day ≈ 11,574,074/sec | 3.65 × 10¹⁴ | 7,400 years | 2.8 years |
Generation rates are order-of-magnitude estimates. Trace ID generation is per-request in distributed tracing systems (one trace ID + multiple span IDs per request). IoT fleet assumes 1 UUID per device-day for telemetry correlation — conservative for some deployments. Amazon retail operation count is a rough estimate from public AWS re:Invent talks about internal service scale.
Look at the "Years to 10⁻⁹ Risk" column — this is the threshold at which the collision probability reaches one in a billion, which is where most engineering teams start to think about adding a uniqueness check. For a large SaaS generating a million UUIDs per second, you hit that threshold in about 33 years. For a global CDN generating 10 million per second, you hit it in 3.3 years. These numbers are small enough to matter over the operational lifetime of a long-lived system — but large enough that you could add collision detection as a database constraint and check for it once per deployment and never see a violation.
The Global CDN row is worth staring at: 3.3 years to a one-in-a-billion collision probability at 10 million UUIDs/sec. If your system is in this ballpark, the correct response is not to panic. It's to add a UNIQUE constraint on the UUID column — which you should do anyway, because UUID collisions from RNG bugs are more likely than collisions from the birthday paradox, and the constraint catches both.
Compare this to the password crack time analysis — another domain where people optimize the visible variable while ignoring the structural one. With passwords, the hash algorithm dominates. With UUIDs, the entropy source dominates. In both cases, the variable everyone talks about — password length, UUID count — is the wrong place to spend your anxiety.
UUID v4 vs v1 vs v7: The Version Choice Matters More Than the Collision Probability
The question "how many UUIDs before a collision" implicitly assumes UUID v4. But version choice changes the answer — not just the collision probability, but what "collision" even means for that version. The RFC 9562 UUID specification defines eight versions, and only one of them (v4) uses pure randomness. The others use timestamps, MAC addresses, namespaces, or a combination — and each model has its own collision semantics.
| UUID Version | Random Bits | Uniqueness Model | Collision Risk | Best For |
|---|---|---|---|---|
| v4 (Random) | 122 | Cryptographic randomness | Mathematically impossible at real scale — IF CSPRNG is used | General purpose. Safe default. |
| v7 (Unix Timestamp + Random) | 74 | Millisecond timestamp + randomness | Collisions only within same millisecond. 74 random bits within each ms = 1.9×10²² space per ms — still astronomically safe. | Database primary keys. Time-sortable. New default (RFC 9562, 2024). |
| v1 (MAC + Timestamp) | 0 | MAC address + 100ns timestamp + clock sequence | Guaranteed unique per MAC — but VMs share MACs. Cloned VMs + v1 = guaranteed collision. | Physical hardware only. Avoid in virtualized/containerized environments. |
| v3 / v5 (Name-Based) | 0 | Deterministic hash of namespace + name | Same input = same UUID. Collision is a feature, not a bug — but only if you understand it. | Content-addressable IDs, namespacing. Not for random uniqueness. |
| v6 (Reordered v1) | 0 | Same as v1, fields reordered for sortability | Same MAC-dependence as v1. Avoid. | Legacy migration only. |
Why UUID v7 Is the New Default
UUID v4 is safe on collision probability. Its operational problem is not collisions — it's index performance. UUID v4 values are randomly distributed, which means they scatter writes across every page of a B-tree index. A Postgres or MySQL table with a UUID v4 primary key will fragment its index, reduce page cache efficiency, and slow down range scans compared to a sequential or time-ordered key. This is the single most common operational complaint about UUIDs, and it has nothing to do with collisions.
UUID v7 (standardized in RFC 9562, May 2024) fixes this by prefixing the UUID with a 48-bit Unix timestamp in milliseconds, followed by 74 random bits. The timestamp prefix means UUIDs generated in different milliseconds are strictly ordered — new UUIDs are always larger than old ones. This gives you B-tree-friendly insertion without giving up collision resistance: 74 random bits per millisecond is a space of 1.9 × 10²² values. To hit the 50% collision threshold within a single millisecond, you would need to generate roughly 5.1 × 10¹¹ UUIDs in that millisecond — a rate of 510 trillion per second, which is not happening on any hardware that exists.
The practical recommendation for new systems in 2026: use UUID v7 for primary keys. You get time-ordered B-tree insertion, 74 bits of collision resistance per millisecond (which is still effectively infinite), and the timestamp gives you creation-time visibility without a separate created_at column lookup. The collision probability estimator is parametrized for v4's 122-bit space because v4 is still the most deployed version, but the math for v7 is the same formula with d = 2^74 — which changes the numbers but not the conclusion: collisions from randomness alone are not going to happen.
⚠️ UUID v1 in Virtualized Environments
UUID v1 guarantees uniqueness by MAC address. In a virtualized or containerized environment, MAC addresses are not unique — they are assigned from a pool, duplicated across clones, and changed on migration.
If you clone a VM that was generating UUID v1, the clone will produce duplicates of every UUID the original generated after the clone point — because the MAC address, timestamp counter, and clock sequence are identical. UUID v1 was designed in the 1990s for physical hardware. It was never intended for a world where servers are cattle, not pets. If your system uses UUID v1 and runs on any form of virtualized infrastructure, you are relying on a uniqueness guarantee that was voided the moment your first VM was cloned. Migrate to v4 or v7.
When Collisions Actually Happened: Production UUID v4 Collision Reports
The math says UUID v4 collisions are impossible at any real scale. But collisions have happened in production. Not because the math was wrong — because the random number generator was wrong. Here are the patterns that have caused real production UUID v4 collisions, drawn from postmortems and bug reports.
Case 1: Go's math/rand in Fast-Starting Containers (2015–2018)
The most cited production UUID collision incident involves Go's math/rand package, which uses a deterministic PRNG seeded by default with the current Unix time in nanoseconds. In a containerized environment where dozens of containers start in the same sub-second window — a Kubernetes Deployment rolling out a new ReplicaSet, for example — every container seeds its PRNG with the same value. Every container then generates the same sequence of "random" UUIDs. The Go UUID library most commonly associated with this bug (github.com/satori/go.uuid, now archived and deprecated) used math/rand instead of crypto/rand for performance reasons. The fix was to use crypto/rand — the CSPRNG that reads from the OS entropy pool — which every maintained UUID library now does by default.
This case is instructive not because a library had a bug — every library has bugs — but because the failure mode was invisible. The UUIDs looked correct. They were valid v4 format with the correct version and variant bits. No validation tool could distinguish them from properly generated UUIDs. Only a UNIQUE constraint violation — or worse, silently corrupted data — revealed the problem.
Case 2: Embedded Systems with No Hardware Entropy Source
Embedded Linux devices and IoT sensors frequently lack a hardware random number generator (hwrng). On first boot, before the kernel entropy pool has been seeded from interrupt timing jitter, /dev/urandom returns deterministic output. If the device generates a UUID during its initial boot sequence — for device identity, telemetry correlation, or configuration tracking — every device of the same hardware revision running the same firmware image generates the same UUID. This is not a UUID library bug. It's a platform initialization bug: the UUID is generated before the entropy pool is ready.
The fix is architectural, not cryptographic: delay UUID generation until after the entropy pool has been seeded, or use a hardware entropy source if available, or seed the PRNG from a factory-provisioned unique value (serial number, MAC address, or a pre-burned random seed). The container resource limit calculator models a related initialization problem — resource constraints that manifest only at startup and are invisible once the system reaches steady state.
Case 3: Cloned VMs with Saved VM State
When a VM is cloned from a snapshot, the entropy pool state in the saved VM image is duplicated. If the clone generates UUIDs before accumulating sufficient new entropy, it will produce the same sequence of UUIDs as the original VM — or as any other clone from the same snapshot. This is the same class of bug as the container case, but harder to detect because VMs often run for days or weeks before anyone notices duplicate UUIDs in a distributed database. The fix is to re-initialize the entropy pool on first boot after cloning — something cloud-init and similar initialization systems handle by reseeding the PRNG from the hypervisor's entropy source, but only if configured to do so.
The common thread across all three cases: the collision was not caused by the birthday paradox catching up with a system at scale. It was caused by a deterministic PRNG producing the same sequence on multiple nodes. The math was never the problem. The operational assumption — "the RNG is random" — was the problem.
The RNG Problem: Where Collisions Really Come From
After reading the previous section, you might conclude that the fix is simple: use crypto/rand instead of math/rand, and move on. That fixes the specific Go library bug. It does not fix the structural problem, which is that UUID collision probability is a function of entropy source quality, not keyspace size — and entropy source quality degrades in ways that the birthday paradox formula does not model.
The birthday paradox assumes independent, uniformly distributed random draws from the keyspace. A CSPRNG seeded from a proper OS entropy pool satisfies this assumption. The assumption breaks when:
- The entropy pool is shared across nodes — cloned VMs, container snapshots, golden images with pre-seeded PRNG state. The draws are no longer independent across nodes; they are perfectly correlated.
- The entropy pool is empty at generation time — early boot in embedded systems, containers that start faster than the kernel can accumulate entropy. On Linux,
/dev/urandomnever blocks but returns low-quality output when the pool is starved. Thegetrandom()syscall (added in Linux 3.17, 2014) blocks until the pool is initialized — use it. - The UUID library uses a userspace PRNG for performance — the Go
math/randbug above is the canonical example, but every language has similar footguns. Python'srandommodule. Java'sjava.util.Random. Node.js'sMath.random(). All of these are fast, deterministic PRNGs designed for simulations and games, not for generating identifiers that must be globally unique. - Fork safety — after a
fork(), the child process inherits the parent's PRNG state. If both the parent and child generate UUIDs after the fork, they will produce identical sequences. This is a niche concern outside of certain server architectures (e.g., pre-fork worker models in Ruby's Unicorn or Python's Gunicorn), but when it bites, it bites hard.
🛡️ The Practical Checklist
Your UUID v4 collision probability is only as good as your entropy source. Here is what actually matters:
- Use the OS CSPRNG.
crypto.randomUUID()in browsers and Node.js.java.util.UUID.randomUUID()in Java (delegates toSecureRandom).os.urandom()orsecretsmodule in Python.crypto/randin Go. These all read from the OS entropy pool. Do not use userspace PRNGs. - Verify the entropy pool is initialized. On Linux, check that
/proc/sys/kernel/random/entropy_availis non-zero before generating UUIDs at boot. On systems usinggetrandom(), this is handled automatically — the call blocks until the pool is ready. - Re-seed after cloning. If your infrastructure clones VMs or containers from a golden image, ensure the first-boot sequence re-seeds the PRNG from a fresh entropy source. Cloud-init handles this on most platforms; verify it.
- Add a UNIQUE constraint on the UUID column. Even if the math says collisions are impossible, database constraints are cheap and RNG bugs are real. The constraint costs you nothing and catches the failure mode the math doesn't model.
This checklist is more valuable than any amount of time spent calculating collision probabilities. The probability that your RNG is misconfigured is higher than the probability of a birthday paradox collision — not because the math is wrong, but because misconfigurations are common and 10⁻¹⁹ probabilities are not. The same pattern shows up in RAID 5 reliability math: the theoretical URE probability gets all the attention, but the real failures come from correlated drive aging, firmware bugs, and human error during rebuilds. The theoretical model is the ceiling. The operational reality is the floor. Plan for the floor.
Practical Guidance for Distributed Systems
If you are building or operating a distributed system that generates UUIDs across multiple nodes — and in 2026, that describes nearly everything — here is the decision framework, stripped of the math and focused on what changes your operational outcomes.
For new systems: use UUID v7. It is standardized (RFC 9562, 2024), it is time-sortable (good for B-tree indexes), and its 74 random bits per millisecond provide collision resistance that exceeds any realistic generation rate. The Go github.com/google/uuid library, Java java.util.UUID (JDK 17+), and Python uuid6 package all support v7 generation. If your language's standard library does not yet support v7, use v4 with a CSPRNG and add a created_at timestamp column — the operational difference between v4 and v7 is index performance, not collision safety.
For existing systems on UUID v4: stay on v4. The migration cost from v4 to v7 — updating every service that generates or consumes UUIDs, handling mixed-version databases, updating validation logic — is not worth the index performance gain unless your database is demonstrably suffering from B-tree fragmentation. Profile your insert performance before you migrate. Most systems are I/O bound on something other than UUID index fragmentation, and the things that are actually slow will surprise you. The DB instance sizing calculator can help you determine whether your database is CPU-bound, memory-bound, or I/O-bound before you spend engineering time on a UUID version migration that might not move the needle.
If you are generating UUIDs at a rate that makes the 10⁻⁹ threshold relevant: add a collision detection layer. The UUID v4 collision probability estimator will tell you where that threshold is for your generation rate. If you are above it — if your system generates trillions of UUIDs per year — add a UNIQUE constraint on the UUID column, retry on constraint violation with a freshly generated UUID, and monitor the retry rate. At any probability below 10⁻⁶, the retry rate will be effectively zero — but when it fires, it will catch an RNG bug you didn't know you had, and that alone justifies the implementation cost.
If you are using UUID v1 in a virtualized environment: stop. Migrate to v4 or v7. The MAC address uniqueness guarantee that v1 relies on does not hold in any virtualized or containerized infrastructure deployed in the last decade. This is not a probability concern — it's a determinism concern. Cloned VMs will produce duplicate UUIDs, and the duplicates will be lexicographically similar because they share the timestamp prefix, making them cluster together in indexes and amplify the data corruption.
If you are generating UUIDs on embedded or IoT devices: ensure the entropy pool is initialized before first UUID generation. Use getrandom() on Linux, which blocks until the pool is ready. If your platform does not have a hardware entropy source, provision a unique seed at manufacturing time and mix it into the PRNG state before the first UUID generation. A factory-provisioned 256-bit seed — burned into secure storage per device — eliminates the entire class of identical-initial-sequence bugs. This is more important than your choice of UUID version.
And one thing that applies universally: add the UNIQUE constraint. It costs one index page per row and catches every collision — mathematical and operational — with zero false negatives. The probability that the constraint fires is astronomically low if your RNG is healthy. The probability that you have an RNG misconfiguration you don't know about is higher than you think. The constraint is insurance against the failure mode the math can't predict.
Frequently Asked Questions
How many UUIDs before a collision?
For UUID v4, the 50% collision threshold is approximately 2.71 × 10¹⁸ (2.71 quintillion) UUIDs. At 1 billion generations per second, reaching this threshold takes roughly 85 years. For a 1% collision probability, you need about 3.26 × 10¹⁷ UUIDs. For a one-in-a-billion (10⁻⁹) probability — the threshold most systems treat as acceptably safe — you can generate roughly 1.03 × 10¹⁴ UUIDs, or about 103 trillion. These numbers assume a cryptographically secure random number generator producing uniformly distributed output. With a flawed RNG, collisions can occur at any scale — and have in production. Use the UUID v4 collision probability estimator to model your exact generation volume.
What is the UUID v4 collision probability at scale?
At 1 billion UUID v4 generations: ~10⁻¹⁹ (effectively impossible). At 1 trillion: ~10⁻¹³ (astronomically unlikely). At 1 quadrillion: ~10⁻⁷ (1 in 10 million). At 2.71 quintillion: ~50%. The probability follows the birthday paradox formula p ≈ n² / (2 × 2¹²²). At any realistic generation rate — even billions per second across an entire datacenter — UUID v4 collisions from randomness alone will not occur within the lifetime of the universe. The real collision risk is not the math. It's flawed random number generators, cloned virtual machines, and containerized systems with insufficient entropy pools. Every documented production UUID v4 collision has been traced to a bad RNG, not to the birthday paradox catching up.
Has a UUID collision ever happened in production?
Yes — but not because the math failed. Every documented production UUID v4 collision has been traced to a flawed random number generator. The most common pattern: containers starting in the same sub-second window, each seeding a deterministic PRNG with the same Unix timestamp, then generating identical UUID sequences. The Go github.com/satori/go.uuid library (now deprecated) was the most prominent case, using math/rand instead of crypto/rand. Other cases include embedded devices generating UUIDs before the entropy pool was initialized, and cloned VMs with duplicated entropy state. In every case, the fix was not "use longer UUIDs" — it was "use a cryptographically secure random number generator with proper entropy seeding."
Which UUID version should I use to avoid collisions?
UUID v7 (RFC 9562, 2024) is the best choice for new systems. It provides 74 random bits per millisecond — a 1.9 × 10²² space within each millisecond — plus a Unix timestamp prefix that gives time-ordering for B-tree index performance. UUID v4 with a CSPRNG is the safe, battle-tested default for existing systems. UUID v1 should be avoided in any virtualized or containerized environment because its uniqueness depends on MAC addresses, which are not unique across cloned VMs. UUID v3 and v5 are deterministic (name-based) and should not be used where random uniqueness is required. For a deeper comparison, see the version comparison table above. The version you choose matters more for operational performance (index fragmentation, sortability) than for collision safety — any version with ≥74 random bits is mathematically safe at real-world scale.
How long would it take to generate enough UUIDs for a collision?
At 1 billion UUID v4 generations per second — roughly the throughput of a large distributed system with hundreds of nodes — reaching the 50% collision threshold takes approximately 85 years. At 1 trillion per second — a rate that would require a dedicated datacenter — it takes about 31 days. At 1 million per second — a busy microservice architecture — it takes about 85,000 years. The 10⁻⁹ risk threshold is reached sooner: about 33 years at 1 million/sec, or 3.3 years at 10 million/sec. For context: even the Amazon retail platform, if every operation generated a UUID v4, would need over 7,000 years to hit 50% collision probability. The relevant time scale is not "how long to a collision" but "how long until my UUID library's PRNG bug gets triggered." The answer to the second question is "unknown, possibly tomorrow." Add a UNIQUE constraint.
Methodology & Disclosure
Collision probability calculations use the exact birthday problem formula p = 1 − ∏(1 − k/d) for k = 1 to n−1, where d = 2^122 ≈ 5.3169 × 10³⁶ for UUID v4 and d = 2^74 ≈ 1.8889 × 10²² for UUID v7 per-millisecond space. The n²/2d approximation is used for readability in prose but exact values are used in the UUID v4 collision probability estimator and in the tables presented here. The approximation error is less than 1% for n ≤ 10¹⁸ and becomes meaningful only as n approaches d, which is not relevant at any real-world generation volume.
System generation rate estimates are order-of-magnitude approximations based on public data: Postgres insert rates from pgbench benchmarks, distributed tracing ID volumes from OpenTelemetry community surveys, IoT device counts from GSMA and Ericsson mobility reports, and Amazon internal service scale from AWS re:Invent talks (approximate, as Amazon does not publish exact UUID generation rates). Actual rates vary by orders of magnitude across deployments. Use the estimator with your measured generation rate, not the reference values here.
Production UUID collision cases are drawn from public postmortems, GitHub issues in UUID library repositories, and personal communication with engineers who encountered them. The Go satori/go.uuid math/rand issue is the most widely cited and best-documented case; the embedded system and cloned VM cases are composite descriptions of failure patterns reported across multiple incident reports. Specific company names are omitted where the incident was not publicly disclosed.
UUID version specifications reference RFC 9562 (May 2024), which obsoleted RFC 4122 (July 2005) and standardized versions 6, 7, and 8 alongside the existing versions 1–5. Version 7 adoption in language standard libraries is current as of July 2026; check your language's UUID library documentation for the latest v7 support status.
Disclosure: jslet is an independent research project. We are not sponsored by any standards body, UUID library maintainer, or infrastructure vendor. The UUID v4 collision probability estimator was built because the author has answered the question "but what if two servers generate the same UUID?" at enough system design reviews to want a tool that answers it definitively with math instead of hand-waving. No affiliate links. No referral codes. No sponsored recommendations.
References & Further Reading
Companion article: UUID v4 vs v7: Why Random Primary Keys Destroy Write Performance — this article covers collision probability. The companion covers what actually matters for your database: B-tree page splits, INSERT throughput, and why v7's timestamp prefix fixes the storage engine behavior that v4's randomness breaks.
- IETF (2024). "RFC 9562 — Universally Unique IDentifiers (UUID)." Obsoletes RFC 4122. Standardizes versions 6, 7, and 8. Defines the 122-bit random space for v4 and the 74-bit per-millisecond space for v7. rfc-editor.org
- Leach, P., Mealling, M., and Salz, R. (2005). "RFC 4122 — A Universally Unique IDentifier (UUID) URN Namespace." The original UUID specification, obsoleted by RFC 9562 in 2024 but still the reference for versions 1–5 in deployed systems. rfc-editor.org
- github.com/google/uuid (2026). "Go UUID Library — v4 and v7 Generation Using crypto/rand." Reference Go implementation supporting RFC 9562 versions 4 and 7 with CSPRNG-backed generation. github.com
- OpenJDK (2024). "java.util.UUID — RFC 9562 v7 Support (JDK 17+)." Java standard library UUID implementation with SecureRandom-backed v4 generation. docs.oracle.com
- OWASP (2026). "Cryptographic Storage Cheat Sheet — Random Number Generation." CSPRNG selection guidance across languages and platforms. owasp.org
- Linux Kernel Documentation (2026). "Random Number Generation — /dev/urandom, getrandom(), and Entropy Pool Initialization." kernel.org
- NIST SP 800-90A Rev. 1 (2015). "Recommendation for Random Number Generation Using Deterministic Random Bit Generators." Technical specification for CSPRNGs used by OS entropy sources. nist.gov
- Birthday Problem — General Reference. "The Birthday Paradox: Probability of Shared Birthdays in a Group of n People." The mathematical foundation for the collision probability formula applied to UUID keyspaces. wikipedia.org
📜 Copyright & Attribution
© 2026 jslet Research. This article is an original work independently researched and published on jslet (jslet.com). All rights reserved.
Sharing & Reprinting: You may share excerpts (up to 200 words) with a mandatory, do-follow link back to this article's canonical URL. Full reproduction, translation, or adaptation requires prior written permission from jslet Research. Commercial republication, AI/LLM training corpus ingestion, and paywalled syndication are expressly prohibited without a licensing agreement.
Preferred citation format:
"UUID v4 Collision Probability at Scale: How Many UUIDs Before a Collision? (2026)" — jslet Research, July 2026.
https://www.jslet.com/uuid-v4-collision-probability-real
📡 Enjoyed this? The birthday paradox is more fun with an RSS reader. Get one engineering briefing per week — zero spam, zero trackers, zero "we value your privacy" modals. RSS Feed → | More options →