Home · Blog · Data

UUID versions explained: which one you actually need

A UUID is 128 bits with a version number hidden in the middle. Version 4 is random, version 7 is time-ordered, version 5 is a hash of a name — and picking the wrong one has real consequences for databases and privacy. A field guide to all five, plus the new trio.

Every UUID carries its version in a single hex digit — the first character of the third group. In 3f8a2c1e-9b4d-4e7a-a5c3-1d2f4b6a8e90, that digit is the 4, and it tells you how the identifier was made: from the current time, from a name, or from pure randomness. Most developers meet UUIDs as a single function call that returns "the random one", but the family is bigger than that, and the differences matter most exactly where UUIDs are used hardest — as database keys and public identifiers.

This guide walks through versions 1 to 5, the newer 6, 7 and 8 standardised in RFC 9562, and ends with a short decision guide. The short version, if you are in a hurry: version 4 for general identifiers, version 7 for database primary keys you insert in volume, version 5 when you need the same input to always produce the same ID.

Key takeaways

  • The version digit sits at a fixed position: the first hex digit of the third group.
  • Version 4 uses 122 bits of randomness; collisions are a practical non-issue at any realistic scale.
  • Version 7 (and 6) sort by creation time, which makes them far friendlier as indexed database keys.
  • Version 1 embeds a timestamp and historically a MAC address — avoid it for public-facing IDs.

Anatomy of 128 bits

A UUID is written as 32 hex digits in five groups separated by hyphens: 8-4-4-4-12. Not all 128 bits are information of the same kind. Four bits are the version. Two or three bits form the variant field — in practice you will see the fourth group start with 8, 9, a or b, which marks the standard RFC layout. What remains for actual content is 122 bits in version 4. That is the number to remember when anyone asks how collision-prone random UUIDs are: after generating a billion of them, the chance that any two coincide is roughly one in 80 million, and it stays negligible until you approach quintillions.

xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
M = version digit (1–8)
N = variant: 8, 9, a or b for the standard layout

Versions 1 to 5: time, names and hashes

VersionBuilt fromCharacter
1Timestamp + node ID (historically a MAC address) + counterSortable by time, but leaks when and roughly where it was minted; the MAC exposure is why it fell from favour.
2Like v1, with local-domain fieldsA DCE security variant you will almost certainly never need.
3MD5 hash of a namespace + nameDeterministic: same input, same UUID, forever. Uses MD5 because the goal is naming, not security.
4122 bits of randomnessThe default everywhere. No meaning embedded, nothing leaked.
5SHA-1 hash of a namespace + nameThe modern deterministic option; prefer it over v3 for new systems.

Deterministic versions (3 and 5) deserve respect: they let independent systems derive the same ID for the same thing without coordination — useful for migrations, deduplication and reproducible data pipelines. Namespaces are themselves UUIDs; the standard predefines four (for DNS names, URLs, OIDs and X.500 names), and hashing, for example, the URL namespace with the string example.com/widgets/42 always yields the same version 5 UUID on any machine.

Versions 6, 7 and 8: the database-friendly generation

Random v4 keys have a hidden cost in databases. Inserts land at random positions in a B-tree index, scattering rows across pages, bloating the index and thrashing caches at scale. Version 6 fixes this by reordering v1's timestamp so the UUID sorts in creation order. Version 7 does it more cleanly: a 48-bit Unix millisecond timestamp first, then random bits. A v7 UUID therefore sorts roughly by insertion time while remaining unique without coordination, and it has become the recommended choice for new primary keys — it is what most recent framework and database releases added support for.

Version 8 is a deliberate escape hatch: a custom format for experimental or vendor-specific layouts that still wants to call itself a UUID. If you are not designing an identifier scheme on purpose, you do not need it. Also worth knowing: the all-zeros "nil" UUID and the all-ones "max" UUID exist as sentinels, and you will occasionally meet them as placeholder values in imported data.

Choosing, in practice

  • API resources, session-ish identifiers, file names, anything public: version 4. Nothing embedded, nothing to infer, supported by every library on earth — including your browser's crypto.randomUUID().
  • Primary keys in a busy relational database: version 7 if your stack supports it, version 4 if not. The insert-locality win shows up exactly when tables get large.
  • Deriving an ID from something that already has a name: version 5, with a namespace you control and document.
  • Avoid for new work: version 1 anywhere the ID is visible to users, because its timestamp reveals creation time to the second and invites enumeration games.

Mistakes and pitfalls

Assuming all UUIDs are random

A v1 or v7 UUID tells an observer roughly when the record was created; a v5 reveals that it was derived from a name — and with a guessable name, the ID itself is guessable. Know which version you are handing out.

Validating UUIDs with a regex that ignores version and variant

A check that accepts any 8-4-4-4-12 hex string will also accept garbage formatted to look right. Validate the version and variant digits too, especially on data you import.

Storing UUIDs as 36-character text in hot tables

Text storage quadruples the bytes versus the native 16-byte binary type most databases offer, and slows comparisons and indexes. It is a performance decision disguised as a formatting one.

Common questions

Can two version 4 UUIDs ever collide?

In principle yes, in practice no: with 122 random bits you would need to generate on the order of 2.7 quintillion before collision odds reach one in a billion. Every realistic failure mode — a broken random generator, a copied database row — is a process bug, not a probability event.

Is a UUID the same as a GUID?

Yes, in practice. GUID is Microsoft's name for the same 128-bit format. A GUID displayed by Windows tooling and a UUID from a web library are interchangeable, subject to byte-order quirks in a few legacy APIs.

Should URLs use UUIDs or sequential IDs?

If outsiders should not be able to guess how many records you have or walk to the next one, UUIDs (v4) are the safer default. Sequential IDs are fine where access is always authorised server-side and enumeration is harmless.

To wrap up

UUIDs reward a moment's thought at design time. Pick the version whose information content matches what you are willing to reveal and whose ordering matches how your storage works, and the format will quietly do its job for decades.

Try it yourself

The UUID generator here produces version 4 identifiers with your browser's crypto API, in bulk if you need them, with the version and variant digits in their proper places.

Open the UUID Generator