CONCEPT Cited by 2 sources
UUID version taxonomy¶
A Universally Unique Identifier (UUID) is a 128-bit identifier designed so independent systems can mint unique IDs without coordination. The 4-bit version field in the first hex position of the third segment encodes which of eight official layouts the UUID uses. Eight versions are specified as of this writing: v1 (time + node), v2 (DCE Security), v3 (namespace + name MD5), v4 (random), v5 (namespace + name SHA-1), v6 (v1 with reordered timestamp), v7 (Unix epoch + random), v8 (vendor-specific escape hatch). (Source: sources/2026-04-21-planetscale-the-problem-with-using-a-uuid-primary-key-in-mysql.)
Version layouts at a glance¶
| Version | Layout | Timestamp epoch | Random? | Sortable by byte? | Typical use |
|---|---|---|---|---|---|
| v1 | time + node | 1582-10-15 (Gregorian start) | No | No (low-time-first) | Legacy time-based |
| v2 | time + POSIX UID | 1582-10-15 | No | No | DCE Security (deprecated in practice) |
| v3 | MD5(namespace + name) | N/A | No (deterministic) | N/A | Content addressing |
| v4 | random | N/A | Yes | No (random) | Default everywhere; the antipattern |
| v5 | SHA-1(namespace + name) | N/A | No (deterministic) | N/A | Content addressing |
| v6 | time + node, reordered | 1582-10-15 | No | Yes | Sortable successor to v1 |
| v7 | Unix-epoch time + random | 1970-01-01 (Unix) | Yes (low bits) | Yes | Modern default for new systems |
| v8 | vendor-specific | n/a | vendor-chosen | vendor-chosen | Custom layouts (shard ID, tenant ID, etc.) |
Version-specific notes¶
v1 — time + node¶
Timestamp in 100-ns increments from Oct 15, 1582 (the
date the Gregorian calendar was widely adopted). Layout
stores time_low → time_mid → time_hi_and_version,
putting the least significant timestamp bits first.
Byte-wise lexicographic sort does not match temporal order.
Final segment is the node ID (traditionally the MAC
address of the generating host) — which makes v1 traceable
back to source hardware.
MySQL's built-in UUID() function generates UUIDv1 only.
See concepts/uuid-to-bin-swap-flag for MySQL's
byte-reorder helper.
v2 — DCE Security¶
Extension of v1 that replaces the time_low segment with a
POSIX user ID, so UUIDs could trace to the user account.
"Since the low_time segment is where much of the
variability of UUIDs reside, replacing this segment
increases the chance of collision. As a result, this
version of the UUID is rarely used."
v3 / v5 — namespace + name hash¶
Deterministic generation: input a namespace UUID + a name string, output a 128-bit hash. v3 uses MD5; v5 uses SHA-1. Same input → same UUID. Useful for content addressing (every URL hashes to the same UUID on any system) but not for primary keys (no uniqueness guarantee across divergent inputs).
v4 — random¶
"Version 4 is known as the random variant because … the
value of the UUID is almost entirely random." All bits
random except the 4-bit version field (4 in the third
segment) and the 2-bit variant field. This is the version
most ORMs and client libraries generate by default, and
the one that triggers the full
concepts/uuid-primary-key-antipattern when used as a
clustered-index PK.
v6 — v1 with flipped timestamp¶
"Version 6 is nearly identical to Version 1. The only difference is that the bits used to capture the timestamp are flipped, meaning the most significant portions of the timestamp are stored first." Byte-wise lexicographic sort now matches temporal order — the fix for v1's sort-order defect. Still uses Gregorian-calendar epoch.
v7 — Unix epoch + random¶
First 48 bits are a Unix epoch millisecond timestamp; remainder is random (plus the version + variant fields). "Integrates the more commonly used Unix Epoch timestamp instead of the Gregorian calendar date used by Version 1. The other key difference is that the node (the value based on the system generating the UUID) is replaced with randomness, making these UUIDs less trackable back to their source."
Operational sweet spot for new systems: sortable by byte, opaque origin (no MAC address), client-side generatable without coordination, and produces near-sequential B+tree-insert locality — see patterns/sequential-primary-key.
v8 — vendor-specific¶
"The latest version that permits vendor-specific implementations while adhering to RFC standards. The only requirement for UUIDv8 is that the version be specified in the first position of the third segment as all other versions." Lets systems embed shard IDs, tenant IDs, timestamp-at-custom-resolution, etc., in a RFC-compliant wrapper.
Picking a version¶
- v4 — only if you want pure randomness and can pay the B+tree penalty (or you're not using it as a PK).
- v7 — default for new systems. Sortable + opaque + client-generatable.
- v6 — if you're stuck in a v1 ecosystem and want byte- sortable values without changing the rest of the stack.
- v1 — only for legacy interop. Use
UUID_TO_BIN(@u, 1)to recover sort-order. - v3 / v5 — content addressing, not PKs.
- v8 — embedding extra information (shard ID, tenant ID) in the UUID itself.
Non-UUID alternatives¶
Once UUID's uniqueness property is assumed, the actual design choice is how the bits are allocated. Three families ship as non-UUID alternatives:
- concepts/snowflake-id — 64-bit
BIGINT, timestamp + machine ID + sequence. Fits in a machine word. - concepts/ulid-identifier — 128-bit base32 string, timestamp + random. Sortable + compact.
- concepts/nanoid-identifier — URL-safe random string at caller-configurable length. Used by PlanetScale's API.
Seen in¶
- sources/2026-04-21-planetscale-the-problem-with-using-a-uuid-primary-key-in-mysql — canonical walkthrough of all eight versions with byte-layout diagrams + Gregorian-epoch disclosure + sort- order analysis + Snowflake/ULID/NanoID comparison.
- sources/2024-09-09-planetscale-b-trees-and-database-indexes — forward-pointer to v7 as the escape hatch for the PK antipattern; v1/v3/v5 lumped together as "random-ish"; v6 and v8 not mentioned.