UUID version 8
Version 8 is deliberately unspecified: six bits are the version and variant, the other 122 are yours. It is the standard's way of saying "put your structure here instead of inventing a new format".
Every team eventually wants a shard number, a tenant, or a different clock inside the identifier. Version 8 is where that goes: a custom layout that still validates as a UUID, fits a uuid column, and survives every library on the way.
018f3c00-0000-8000-8000-0000deadbeefoutuuid · RFC 9562 (10xx) · version 8Valid v8 — the version nibble is 8 and the variant is 10xx
018f3c00-0000-8000-0000-0000deadbeefoutuuid · NCS (0xxx) — reserved, backward compatibility · version 8 · non-rfcSame bits, wrong variant nibble: no longer an RFC 9562 identifier
On this page (7)
What the standard claims, and what it leaves#
Bits 48-51 must read 1000 and bits 64-65 must read 10. Everything else is yours: three runs of 48, 12 and 62 bits, split by the two fixed fields. That awkward split is the main design constraint, because a field cannot straddle the version or variant without being reassembled on read.
RFC 9562 § 5.8 · UUID Version 8The deliberately empty specification
What people put in one#
- A clock with a different epoch or resolution than v7 offers — microseconds, or a domain epoch that buys extra years.
- A shard or partition number, so routing needs no lookup.
- A tenant identifier, so a leaked row cannot be re-keyed into another tenant.
- A short type tag, so an identifier in a log says what it names.
- A checksum over the rest, to catch transcription errors before a database round trip.
What you give up#
Opacity, mostly. The standard's advice is that an identifier should not carry meaning others can parse, because everything encoded in it becomes a contract you cannot change and information you cannot un-leak. A tenant id in the key means the key tells an outsider how many tenants you have and which one a row belongs to.
RFC 9562 § 6.12 · OpacityOpacity: the argument against putting meaning in an identifier
You also give up interoperability of meaning: another system sees a valid v8 and can read nothing from it. Write the layout down next to the schema, with bit offsets, or the next engineer will reverse-engineer it from examples.
Staying sortable#
If ordering matters, the time field has to lead, as in v7: the first 48 bits, most significant first. Put a shard number in front instead and you have grouped by shard, not ordered by time, and the index will behave accordingly.
RFC 9562 § 6.11 · SortingSorting, which a custom layout has to earn for itself
Questions people actually ask#
What is a UUID v8 for?
Custom layouts. The standard fixes only the version and variant bits so that application-specific structure can live in a value that is still a valid UUID.
Can I put a timestamp in a v8?
Yes, and put it first if you want the identifiers to sort. v8 is the right home for a clock that v7 cannot express, such as microseconds or a different epoch.
Will libraries accept a v8?
Parsing and storage yes, because it is a well-formed UUID. Decoding the meaning is on you; nothing else knows your layout.
Related#
Browse the reference
Start here
Making and converting in bulk
Converting a UUID
Reading one
The versions, in order
In a database
ULID and the alternatives
Running the tool