What a UUID actually is
A UUID — Universally Unique Identifier, sometimes called a GUID in the Microsoft world — is a 128-bit number. That’s it. Everything else about it is convention. By tradition it’s written as 32 hexadecimal digits split into five groups by hyphens:
123e4567-e89b-12d3-a456-426614174000
The groups always follow the same 8-4-4-4-12 digit pattern, which adds up to those 32 hex characters. The hyphens are purely for human readability; the value is the same 128 bits with or without them. You can generate UUIDs in any of these forms with the free Random UUID Generator, including a no-hyphen option for systems that store the raw 32-character string.
The point of a UUID is to let anyone, anywhere, mint an identifier that won’t clash with one minted by someone else — without asking a central authority first. A database in Mumbai and a phone in São Paulo can each create a UUID at the same instant and be confident the two values differ. That property is what makes UUIDs the backbone of distributed systems, where coordinating a shared counter would be slow or impossible.
How uniqueness works without coordination
There is no registry of issued UUIDs. Nothing checks whether the value you just generated already exists. Instead, UUIDs rely on probability: the space of possible values is so enormous that an accidental collision is, for practical purposes, impossible.
A version 4 UUID reserves a handful of bits to mark its version and variant, leaving 122 random bits. That’s about 5.3 x 10^36 distinct values. To put that in perspective, you could generate a billion UUIDs every second for a hundred years and your odds of ever seeing a single duplicate would still be vanishingly small. This is the same reasoning behind the “birthday problem,” and the math works out firmly in your favour at these scales.
The catch is that this guarantee only holds if the random bits are actually random. A generator that leans on a weak source — like JavaScript’s Math.random, which is not designed for unpredictability — can produce patterns that increase collision risk and, worse, make IDs guessable. That’s why a good generator pulls its bytes from a cryptographically strong source. The browser-based tool here uses crypto.getRandomValues, the same source you’d use for security tokens.
The versions that matter today
The UUID specification (RFC 9562, which updated the older RFC 4122) defines several versions. In modern application code you’ll almost always reach for one of three.
Version 4 — random
Version 4 fills every non-reserved bit with random data. Two fields are fixed: a four-bit version marker set to 4, and a two-bit variant marker. Everything else is noise. The result is an identifier that carries no information about when or where it was made — it’s just unpredictable.
That unpredictability is v4’s strength. When you don’t want anyone to guess the next ID in a sequence — API request IDs, password-reset tokens embedded in links, object names that shouldn’t be enumerable — v4 is the right tool. Its weakness shows up only when you use it as a database primary key, which we’ll come back to.
Version 7 — time-ordered
Version 7 is the newer, increasingly recommended option. It places a 48-bit Unix millisecond timestamp at the very front of the value, then fills the remaining bits with random data (still setting the version marker to 7 and the variant bits). Because the timestamp leads, v7 UUIDs generated later are numerically larger than ones generated earlier. In other words, v7 values sort by creation time.
That single property solves the biggest practical problem with v4. It also means you can extract a rough creation time from a v7 UUID, which can be handy for debugging — though it also means v7 is not secret, since it leaks when it was made.
The nil UUID
The nil UUID is the all-zero special case: 00000000-0000-0000-0000-000000000000. It’s defined by the spec as a reserved value, and it’s genuinely useful as an explicit “no identifier yet” placeholder, a default in a UUID column, or a stable, predictable value in test fixtures where a random one would make assertions flaky.
Why v7 is better for database keys
When you use a UUID as a primary key, most databases store rows in an index ordered by that key — typically a B-tree. The behaviour of that index depends heavily on whether new keys arrive in order.
With v4, every new key lands at a random position in the index. The database has to insert into the middle of the structure over and over, splitting pages and scattering writes across storage. Over millions of rows this fragments the index, bloats it, and slows down inserts. It also hurts cache locality, because rows created together end up physically far apart.
With v7, every new key is larger than the last, so inserts always append to the end of the index — the same friendly pattern as an auto-incrementing integer. You get sequential writes, tighter pages, and better cache behaviour, while still keeping the decentralised, no-coordination benefit of UUIDs. That combination is why v7 has quickly become the default recommendation for new schemas. You can generate a batch of v7 keys for testing with the UUID generator and watch how they sort in creation order.
Choosing the right version
A simple rule of thumb:
- Reach for v7 when the UUID is a database key, a sort key, or anything where time-ordering helps. This is most application data.
- Reach for v4 when the UUID must be unguessable and must reveal nothing about timing — public tokens, request IDs that double as secrets, enumerable-resource protection.
- Use the nil UUID as a deliberate placeholder or test constant, never as a real identifier.
One thing worth stressing: a UUID is an identifier, not a secret by default. v4 is unpredictable enough to act as a bearer token in many cases, but if a value truly guards access, treat it with the same care you’d give a password or API key. For the broader principles of generating values that resist guessing, see How to Create a Strong Password, which covers the same randomness-and-entropy ideas from the credential side.
Formatting and storage tips
- Hyphens are cosmetic. Store the canonical hyphenated form if your column type is text, or strip hyphens for a compact 32-character key — just be consistent across your codebase.
- Case is cosmetic too. Hex is hex;
Aequalsa. Pick one case and normalise on the way in so lookups don’t miss. - Prefer a native UUID column type when your database offers one (16 raw bytes) over a 36-character string — it’s smaller and indexes faster.
- Don’t parse meaning out of v4. It encodes nothing. Only v7 carries a timestamp, and even then, don’t rely on it for anything that matters for correctness.
Wrapping up
UUIDs give you globally unique identifiers without a central coordinator, trading a registry for overwhelming probability. Version 4 buys you unpredictability; version 7 buys you that same uniqueness plus time-ordering that plays nicely with databases; the nil UUID gives you a clean placeholder. Pick v7 for keys, v4 for secrets, and let a cryptographically strong generator do the random part for you. When you’re ready to create some, the Random UUID Generator produces all three formats in bulk, entirely in your browser.