Developer FIELD NOTES · 4 MIN READ
How UUIDs Work
How 128-bit identifiers stay unique with zero coordination: versions 1/4/7, the 122-bit collision math, and the nil and max special values.
Every minute, millions of computers create identifiers that must never collide — with no central registry, no coordination, and no internet connection required. That trick is the UUID: a 128-bit identifier designed so that two machines, anywhere, can each roll their own unique values and be mathematically certain they will never step on each other. Here is how a fixed 128 bits delivers that guarantee.
Anatomy: 32 hex digits, 128 bits, and two embedded clues
A UUID is written as 32 hexadecimal digits in five groups, 8-4-4-4-12:
550e8400-e29b-41d4-a716-446655440000
└─────8────┘└─4─┘└─4─┘└─4─┘└─────12───────┘
Thirty-two hex digits × 4 bits each = 128 bits. Two positions in that string are reserved and tell you how the UUID was made. The version is the first hex digit of the third group — here the 4, meaning "random". The variant is the first hex digit of the fourth group: an 8, 9, a, or b puts the top bits at 10xx, marking the standard RFC 4122 layout. Everything else is payload, and what fills the payload is exactly what separates the versions.
Time-based versions: uniqueness from the clock
Version 1, the oldest scheme, builds the payload from place and time: a 60-bit timestamp, a clock-sequence counter to survive clock rollback, and the machine's MAC address as the node. Uniqueness comes from the fact that no two network cards share a MAC and no moment happens twice — but it leaks both. A v1 UUID reveals when it was made and from which hardware, which turned out to be a privacy problem (early database systems famously used MAC addresses to trace documents across machines). Successor versions kept the clock but shed the leak: v6 reorders v1's fields so values sort chronologically, and v7 timestamps with Unix epoch milliseconds and fills the rest with random bits. Sortable identifiers matter for databases: inserting time-ordered keys into a B-tree index touches the rightmost page instead of scattering writes at random, which is why v7 has become the popular choice for new systems.
Version 4: uniqueness from randomness
Version 4 takes the opposite bet: ignore the clock entirely and fill the payload with random bits. Of the 128 bits, 6 are spoken for (4 version bits + 2 variant bits), leaving 122 random bits. Any well-behaved random source gives values that are unrelated to time, machine, or each other — no MAC leaks, no timestamps, nothing to correlate. The only engineering requirement is a proper random generator: a browser or OS cryptographic source such as crypto.getRandomValues, not a predictable pseudo-random sequence, if the identifier is ever used in a security-sensitive role.
The collision math: why 122 bits is enough
"Random" sounds like it should eventually collide, and it would — on human timescales the numbers are absurd. Collisions follow the birthday problem: the chance of any collision among n UUIDs is approximately n² / (2 × 2¹²²). To even reach a 50% chance of a single collision you would need about 2.6 quintillion UUIDs (2.6 × 10¹⁸) — at one billion generated per second, that is roughly 80 years of round-the-clock generation. At more realistic scale the odds collapse further: a system that stores a trillion UUIDs carries about a 1-in-10-trillion chance of one collision, and even 103 trillion UUIDs leave only a one-in-a-billion chance. That is why v4 is treated as collision-free in practice: the failure mode is not worth engineering for, because it is outnumbered by hardware errors by many orders of magnitude.
Special values, name-based UUIDs, and what validation can't tell you
Two reserved values sit outside the version system: the nil UUID (00000000-0000-0000-0000-000000000000, all zero bits, meaning "no UUID") and the max UUID (all bits one), added as explicit sentinels so tools can distinguish a real identifier from an empty one. A different family altogether, versions 3 and 5, are name-based: they hash a name inside a namespace with MD5 (v3) or SHA-1 (v5), which makes them deterministic — the same name always yields the same UUID. That is useful when you need "derive the same ID from the same input on every machine," and it is the one version where uniqueness depends on the input, not on randomness.
One more distinction saves confusion: valid is not the same as unique. A validator can confirm the 8-4-4-4-12 shape, read the version and variant, normalise braced or urn:uuid: forms to canonical lowercase — and none of that proves the value was never issued. Uniqueness comes from how the UUID was generated, not from what it looks like.
Try it yourself
Generate batch after batch of random v4 identifiers with the UUID Generator — it uses the browser's cryptographic random source, so the 122-bit guarantee is real, and you can create up to 100 at once. Paste any UUID — hyphenated, braced, compact, or urn-form — into the UUID Validator to see its canonical form, decoded version (1 through 8), variant, and whether it is nil or max. And to see how the name-based family gets its determinism, run the same string twice through the Hash Generator and watch MD5 or SHA-1 return the identical digest every time — the same property v3 and v5 UUIDs are built on.