Why versions exist
A UUID is always 128 bits in the same 8-4-4-4-12 format, but the 122 non-fixed bits can be filled in very different ways depending on the purpose. The version nibble — the first digit of the third group — tells you how those bits were produced. RFC 9562 formalises eight approaches, from pure randomness to deterministic hashing to timestamp-based ordering.
Not all versions are equal. Some are deprecated, some are niche, and two are the default choices for nearly all new work.
v1 — Timestamp and MAC address
Version 1 was the original UUID specification. It encodes a 60-bit timestamp (100-nanosecond intervals since October 1582), a clock sequence, and the MAC address of the network interface that generated it.
xxxxxxxx-xxxx-1xxx-yxxx-xxxxxxxxxxxx
^^^^^^^^^^^^ MAC address (48 bits)
^ version = 1
Problems:
- Privacy. The MAC address uniquely identifies the physical machine. Any v1 UUID leaks which hardware generated it.
- Poor sort order. The timestamp is split across three fields in non-chronological byte order, so v1 UUIDs do not sort by creation time as stored. v6 was created specifically to fix this.
- Clock dependency. If the system clock goes backward the generator must use the clock sequence to avoid duplicates, which adds complexity.
Verdict: Do not use for new work. Use v7 instead.
v2 — DCE Security
Version 2 is defined by the DCE (Distributed Computing Environment) standard, not RFC 9562. It embeds a POSIX UID or GID in the lower bits of the timestamp. It is rarely encountered outside of DCE-based systems and has no practical use in modern software.
Verdict: Ignore entirely.
v3 — Name-based, MD5
Version 3 hashes a namespace UUID and a name string with MD5, then stamps the version and variant bits into the result. The same namespace + name always produces the same UUID.
import uuid
ns = uuid.NAMESPACE_URL
result = uuid.uuid3(ns, "https://example.com")
# always the same value for this namespace + name
Problems: MD5 is cryptographically broken. v3 exists only for backward compatibility with systems that predate v5.
Verdict: Use v5 instead for all new name-based UUIDs.
v4 — Random
Version 4 fills 122 bits with cryptographically secure randomness. The version and variant nibbles account for the remaining 6 bits. There is no timestamp, no machine identity, no ordering.
xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
^ version = 4
^ variant = 8, 9, a, or b
Properties:
- Unpredictable — output is indistinguishable from random bytes
- No information leakage about when or where it was created
- Collision-safe in practice — approximately 2.7 × 10¹⁸ UUIDs needed before a collision becomes likely
- Available natively as
crypto.randomUUID()in all modern browsers and Node.js
Verdict: The default choice for any externally visible identifier — URLs, tokens, share links, public-facing IDs. If you are unsure, start with v4.
v5 — Name-based, SHA-1
Version 5 is identical to v3 but uses SHA-1 instead of MD5. Given the same namespace and name, it always returns the same UUID. The result is deterministic and reproducible on any machine without storing anything.
import uuid
# Standard namespaces defined by RFC 9562
ns_url = uuid.NAMESPACE_URL
ns_dns = uuid.NAMESPACE_DNS
ns_oid = uuid.NAMESPACE_OID
# Derive a stable UUID from a URL
page_id = uuid.uuid5(ns_url, "https://example.com/products/123")
# → always the same value
Use cases:
- Deriving a stable database ID from a natural key (URL, SKU, path) without a lookup table
- Content-addressed identifiers — the ID is a function of the content, not of when it was created
- Generating reproducible test fixtures
Caveat: SHA-1 is not collision-resistant for adversarial inputs, but that is not the threat model here — you control both the namespace and the name. For general-purpose unique IDs, v4 is simpler.
Verdict: Use when you need a deterministic UUID derived from existing data.
v6 — Reordered timestamp
Version 6 takes the v1 timestamp and reorders the bytes so the UUID sorts chronologically. It was designed as a drop-in replacement for v1 in systems that need sortable time-based UUIDs but cannot change their v1 infrastructure.
Verdict: Only relevant when migrating from v1. For new work, use v7 — it is cleaner and more widely supported.
v7 — Unix timestamp and random
Version 7 is the modern time-ordered UUID. The first 48 bits are a big-endian Unix millisecond timestamp. The remaining 74 bits carry randomness, with an optional 12-bit monotonic counter (RFC 9562 §6.2 Method 1) ensuring that values minted within the same millisecond sort correctly.
xxxxxxxx-xxxx-7xxx-yxxx-xxxxxxxxxxxx
^^^^^^^^^^^^^^^^ 48-bit Unix ms timestamp (high bits)
^ version = 7
^ variant = 8, 9, a, or b
^^^^^^^^^^^^^^^^^^^^ random bits + optional counter
Properties:
- Sorts chronologically as a string, as bytes, or as a native
uuidcolumn — no special handling needed - Behaves like an auto-increment integer for B-tree purposes: consecutive inserts cluster on the same index leaf page
- Still globally unique — the random suffix makes collisions negligible even at high generation rates
- Embeds creation time — anyone holding the UUID can read the millisecond it was created
Verdict: The default choice for database primary keys, event IDs, and any internal identifier where creation order is useful. Use v4 when the timestamp must not be visible externally.
v8 — Custom
Version 8 reserves only the version nibble (value 8) and the variant bits. The remaining 122 bits are entirely application-defined. RFC 9562 provides no further structure — v8 is an escape hatch for layouts that do not fit any other version.
Verdict: Only for specialised application-specific schemes. Nothing off-the-shelf uses v8.
Choosing the right version
| You need… | Use |
|---|---|
| A random opaque ID for URLs, tokens, links | v4 |
| A database primary key or event ID | v7 |
| A stable ID derived from a name or URL | v5 |
| Compatibility with a legacy v1 system | v6 (migration only) |
| A legacy name-based ID (MD5) | v3 (compatibility only) |
| A custom application-specific layout | v8 |
For the vast majority of new work the choice is binary: v7 for storage, v4 for exposure. The other versions exist for specific compatibility or determinism requirements.
For a direct comparison of the two main options, see UUID v4 vs UUID v7. To generate one now, use the UUID v7 generator or UUID v4 generator.
Frequently asked questions
Which UUID version should I use?
For database primary keys and event IDs, use v7 — its millisecond timestamp prefix keeps B-tree inserts sequential. For externally visible identifiers like URLs and tokens, use v4 — pure randomness with no timestamp leakage. v5 is the choice when you need a deterministic UUID derived from a name or URL.
Is UUID v1 still used?
It exists in legacy systems but should not be used for new work. v1 embeds the MAC address of the generating machine (a privacy leak) and has poor B-tree sort behaviour. UUID v7 supersedes it entirely.
Should I use v4 or v7?
Use v7 for database primary keys (time-sortable, index-friendly) and v4 for anything where creation order could leak information, like tokens or share links.
What are the UUID versions?
RFC 9562 defines versions 1 through 8. v1 uses a timestamp and MAC address, v3 and v5 are name-based (MD5 and SHA-1), v4 is random, v6 reorders v1 for sortability, v7 uses a millisecond timestamp with random bits, and v8 is custom. v4 and v7 are the two recommended for new work.
What is UUID v5 used for?
UUID v5 generates a deterministic identifier from a namespace and a name using SHA-1. Given the same inputs it always returns the same UUID, which makes it useful for deriving stable IDs from existing data — a URL, a file path, a product SKU — without storing a mapping table.
Is UUID v1 still used?
It exists in legacy systems but should not be used for new work. v1 embeds the MAC address of the generating machine, which is a privacy leak, and its timestamp byte order causes poor B-tree sort behaviour. UUID v7 supersedes it.
What is UUID v8?
v8 is a free-form version — RFC 9562 reserves the version bits but leaves the remaining 122 bits entirely to the implementer. It is intended for application-specific or experimental layouts that do not fit any other version. Nothing in v8 is standardised beyond the version nibble and variant bits.