RFC 9562 Explained: The Modern Standard for UUID Versions 6, 7, and 8
A comprehensive developer guide to IETF RFC 9562. Discover why the standard was revised in 2024, how UUIDv7 fixes database indexing, and how to migrate legacy identifiers.
For nearly two decades, software engineers building distributed systems relied on RFC 4122, published in July 2005. That document gave us the identifiers we use every day: the timestamp-based UUIDv1, the name-hashed UUIDv3 and v5, and the ubiquitous random UUIDv4.
While RFC 4122 served the early internet well, modern engineering workflows exposed fundamental limitations:
- UUIDv1 leached hardware information by exposing network MAC addresses and relied on an awkward Gregorian calendar epoch (October 15, 1582) that required complex bit shifting.
- UUIDv4 solved privacy by offering 122 bits of pure pseudorandom entropy, but introduced severe performance degradation in relational databases due to random insertion patterns in B-Tree indexes.
- Developers began inventing their own proprietary, non-standard timestamped formatsโsuch as ULID, KSUID, and Snowflake IDsโfragmenting the ecosystem.
In May 2024, the Internet Engineering Task Force (IETF) officially published RFC 9562: Universally Unique IDentifiers (UUIDs), obsoleting RFC 4122. This standard formalizes three new identifier versions: Version 6, Version 7, and Version 8.
Here is a practical breakdown of what changed, how each new version works, and how to use them in modern production architectures.
The New UUID Versions at a Glance
| Version | Primary Characteristic | Epoch & Ordering | Best Use Case |
|---|---|---|---|
| UUIDv1 (Legacy) | Gregorian timestamp + MAC | Reverse order bits | Legacy telecom & DCE systems |
| UUIDv4 (Current) | Pure random entropy (122 bits) | Unordered / Random | Ephemeral session tokens & nonces |
| UUIDv6 (New) | Re-ordered Gregorian timestamp | High-to-low bit order | Drop-in backward compatibility with v1 |
| UUIDv7 (New) | Unix millisecond timestamp + entropy | Big-endian chronological | Default primary keys for databases |
| UUIDv8 (New) | Custom vendor-defined structure | User-configured | Specialized hardware or domain rules |
UUIDv7: The Star of RFC 9562
Among the additions, UUIDv7 is the most impactful for everyday application development. It was engineered specifically to solve the database indexing problem of UUIDv4 while maintaining total independence from centralized coordinating servers.
Bit Structure of UUIDv7
A UUIDv7 string is 128 bits (16 bytes) formatted in standard 8-4-4-4-12 hexadecimal notation (018e3a2b-8a5c-7d90-b321-4f8a1c9e2b34). The layout is structured as follows:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| unix_ts_ms |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| unix_ts_ms | ver | rand_a |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|var| rand_b |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| rand_b |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
unix_ts_ms(48 bits): A 48-bit unsigned integer holding the number of milliseconds since the Unix epoch (January 1, 1970, 00:00:00 UTC). This gives UUIDv7 natural sortability until approximately the year 10,889 AD.ver(4 bits): Set to binary0111(hexadecimal7) indicating UUID Version 7.rand_a(12 bits): Pseudorandom bits sourced from a cryptographically secure random number generator (CSPRNG), or an optional sub-millisecond counter for high-frequency writes.var(2 bits): Set to binary10(Variant 1 under RFC 9562 / RFC 4122).rand_b(62 bits): Additional pseudorandom bits.
Total entropy: 74 bits of cryptographic randomness combined with a millisecond timestamp. The collision probability remains virtually zero (less than 1 in billions across concurrent nodes), while guaranteeing strict chronological sorting.
Why UUIDv7 Transforms Database Performance
When inserting rows indexed by a standard random UUIDv4, each new key lands at an arbitrary location in the databaseโs B-Tree index.
As your table grows beyond the size of RAM:
- Random inserts force the storage engine to read unrelated index pages from disk into memory.
- Existing index pages become full, causing frequent B-Tree page splits.
- The table index fragments heavily, increasing storage overhead and drastically reducing write throughput.
With UUIDv7, every new ID generated has a greater timestamp value than earlier ones. Inserts always append to the right-most edge of the B-Tree leaf pages:
- Index pages remain densely packed (approaching 90โ95% fill factor).
- Page splits drop to near zero during sequential inserts.
- Cache hit ratios stay high because recent writes operate within hot memory pages.
What About UUIDv6 and UUIDv8?
UUIDv6: Legacy Bridge
UUIDv6 exists solely for systems that currently rely on UUIDv1 and cannot change their timestamp epoch without breaking backward compatibility.
UUIDv1 placed the least significant bits of the timestamp at the beginning of the string (time_low), making sorting impossible. UUIDv6 rearranges those identical 60-bit Gregorian timestamp bits from most-significant to least-significant. If you are starting a new greenfield project, skip v6 and choose v7.
UUIDv8: Experimental & Custom Formats
UUIDv8 provides an RFC-compliant container for custom or experimental identifier schemes that require 128-bit representation. The only requirement under RFC 9562 is that the 4-bit version field (ver = 8) and the 2-bit variant field (var = 10) are preserved. The remaining 122 bits can be tailored to proprietary needs, such as embedding tenant IDs, hardware cluster coordinates, or custom nanosecond clocks.
Generating UUIDv7 in Modern JavaScript
In modern browsers and Node.js runtimes (Node 20+), you can generate RFC 9562 UUIDv7 values using the built-in crypto interface without any third-party dependencies:
export function generateUUIDv7(): string {
const bytes = new Uint8Array(16);
crypto.getRandomValues(bytes);
// 48-bit Unix timestamp in milliseconds
const now = Date.now();
bytes[0] = (now >>> 40) & 0xff;
bytes[1] = (now >>> 32) & 0xff;
bytes[2] = (now >>> 24) & 0xff;
bytes[3] = (now >>> 16) & 0xff;
bytes[4] = (now >>> 8) & 0xff;
bytes[5] = now & 0xff;
// Version 7: 0111 in bits 4-7 of byte 6
bytes[6] = (bytes[6] & 0x0f) | 0x70;
// Variant 1: 10xx in bits 6-7 of byte 8
bytes[8] = (bytes[8] & 0x3f) | 0x80;
// Convert bytes to standard 8-4-4-4-12 hex string
const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
}
At Modern UUID, this exact calculation runs completely inside your client-side browser thread using hardware-backed entropy, ensuring zero server latency and zero data leakage.
Migration Checklist: Moving from UUIDv4 to v7
Migrating an existing application to UUIDv7 is straightforward because both versions share the exact same 128-bit representation, 36-character string format, and database data types (such as UUID in PostgreSQL):
- Storage Compatibility: No database schema alterations are needed. If your column type is
UUIDorBINARY(16), UUIDv7 fits without migration. - Gradual Adoption: You can begin generating UUIDv7 for all new rows immediately. Old UUIDv4 rows will remain valid alongside new UUIDv7 records in the same table.
- Inspect Timestamps When Debugging: Because the first 48 bits represent epoch milliseconds, you can extract the exact creation timestamp of any record directly from its ID without querying audit tables.
RFC 9562 represents a thoughtful, pragmatic modernization of distributed identity. By uniting the collision resistance of random identifiers with the mechanical efficiency of sequential timestamps, UUIDv7 has rapidly established itself as the new industry benchmark.
Modern UUID Core Engineering Team
Verified AuthorsEngineers specializing in distributed systems, cryptography, and client-side web performance. All implementations and architectural guides are validated against official IETF RFC test vectors and W3C Web Cryptography API standards.