UUIDv7 Generator (Live RFC 9562 Time-Ordered ID Tool)
Generate official IETF RFC 9562 UUIDv7 identifiers in real time. Features monotonic 48-bit millisecond time-ordering to eliminate database B-Tree index fragmentation, bulk generation up to 100 IDs, and an interactive timestamp decoder.
UUIDv7 is a modern 128-bit identifier standardized in IETF RFC 9562 that combines a 48-bit Unix timestamp in milliseconds with 74 bits of cryptographically secure pseudorandomness. Unlike purely random UUIDv4, UUIDv7 values sort chronologically, preventing database index fragmentation and mid-page splits.
The Bit-Level Anatomy of RFC 9562 UUIDv7
Ratified by the Internet Engineering Task Force in May 2024, RFC 9562 obsoletes legacy RFC 4122. The 128-bit memory payload of UUIDv7 is structured specifically for temporal locality:
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 | (Bits 0-31) +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | unix_ts_ms | ver | rand_a | (Bits 32-63) +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |var| rand_b | (Bits 64-95) +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | rand_b | (Bits 96-127) +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
unix_ts_ms(48 Bits): Big-endian integer recording milliseconds elapsed since the Unix Epoch (1970-01-01). Immune to the Year 2038 bug—will not overflow until August 2, 10889 AD.ver(4 Bits): Binary literal0111(hexadecimal0x7), confirming UUID Version 7.rand_a(12 Bits): High-entropy pseudorandom bits or a sub-millisecond sequence counter.var(2 Bits): Binary literal10, indicating RFC 4122/9562 variant compatibility.rand_b(62 Bits): Pure cryptographically secure pseudorandom entropy.
Why UUIDv7 Restores Relational Database Insert Performance
Modern database storage engines (such as PostgreSQL's B-Tree indexes and MySQL's InnoDB clustered primary keys) organize records using B+ Trees.
- The UUIDv4 Bottleneck: Because UUIDv4 is 100% random, every
INSERTquery lands on an arbitrary leaf node in the B-Tree. When a page exceeds its capacity (typically 8KB or 16KB), the engine halts writes to execute a mid-page split, leaving index pages half-empty (~50% fill factor) and displacing active data from RAM buffer pool caches. - The UUIDv7 Solution: Because the first 48 bits encode current millisecond time, newly inserted records append sequentially to the rightmost leaf node of the B-Tree. Writes execute sequentially like an auto-increment integer, maintaining a 90%+ index fill factor while retaining completely decentralized generation across distributed microservices.
UUIDv4 vs. UUIDv7 vs. ULID Comparison Matrix
| Feature | UUIDv4 (Legacy) | ULID (Community) | UUIDv7 (RFC 9562) |
|---|---|---|---|
| Time Ordering | None (Random) | Millisecond | Millisecond (Monotonic) |
| Native SQL 16-Byte Column | Yes (UUID / BINARY) | No (Requires Base32 string) | Yes (100% Drop-In Compatible) |
| Official IETF Standardization | RFC 4122 (Obsolete) | None (Informal Spec) | RFC 9562 (Official Standard) |
| B-Tree Fragmentation | Severe (> 40%) | Minimal (< 3%) | Minimal (< 2%) |
Programmatic UUIDv7 Implementation in Node.js & Python
To generate RFC 9562 compliant UUIDv7 identifiers programmatically in your applications:
Node.js & TypeScript (Native Web Crypto):
import { webcrypto } from 'node:crypto';
export function uuidv7(): string {
const bytes = new Uint8Array(16);
webcrypto.getRandomValues(bytes);
const ts = Date.now();
// 48-bit timestamp
bytes[0] = (ts / 0x10000000000) & 0xff;
bytes[1] = (ts / 0x100000000) & 0xff;
bytes[2] = (ts / 0x1000000) & 0xff;
bytes[3] = (ts / 0x10000) & 0xff;
bytes[4] = (ts / 0x100) & 0xff;
bytes[5] = ts & 0xff;
// Version 7 & Variant 10
bytes[6] = (bytes[6] & 0x0f) | 0x70;
bytes[8] = (bytes[8] & 0x3f) | 0x80;
return [...bytes].map((b, i) =>
([4, 6, 8, 10].includes(i) ? '-' : '') + b.toString(16).padStart(2, '0')
).join('');
}
Python (Standard Library):
import time, os, uuid
def generate_uuidv7() -> uuid.UUID:
ts_ms = int(time.time() * 1000)
rand_bytes = bytearray(os.urandom(16))
# Pack 48-bit timestamp
rand_bytes[0:6] = ts_ms.to_bytes(6, byteorder='big')
# Version 7
rand_bytes[6] = (rand_bytes[6] & 0x0F) | 0x70
# Variant 10
rand_bytes[8] = (rand_bytes[8] & 0x3F) | 0x80
return uuid.UUID(bytes=bytes(rand_bytes))
Related Identifier & Developer Utilities:
- Full UUID / GUID Generator Hub — Generate standard random UUIDv4 identifiers in bulk.
- RFC 9562 Deep Dive: What’s New in UUIDv6, UUIDv7 & UUIDv8 — Complete architectural analysis.
- UUIDv4 vs. UUIDv7 vs. ULID Database Benchmarks — Write throughput and indexing benchmarks.
- NanoID vs. UUID Architecture Guide — Compact URL identifiers compared.
Frequently Asked Questions
Can I store UUIDv7 in an existing standard UUID database column?
Yes. UUIDv7 adheres strictly to the 128-bit binary layout, 36-character hyphenated string format, and RFC variant flags. It is 100% drop-in compatible with native PostgreSQL, MySQL, CockroachDB, and SQLite UUID column types without schema migrations.
Does UUIDv7 suffer from the Year 2038 timestamp problem?
No. UUIDv7 dedicates a 48-bit unsigned integer to the Unix millisecond timestamp. This allows timekeeping to continue without rollover until August 2, 10889 AD, completely bypassing the 32-bit Year 2038 integer bug.
How does UUIDv7 prevent collisions within the same millisecond?
UUIDv7 dedicates 74 bits to cryptographic randomness (or a combination of sub-millisecond sequence counter and randomness). An application would need to generate over 190,000 UUIDv7s within a single millisecond to reach a one-in-a-billion collision chance.
Why is UUIDv7 better than ULID?
While both provide millisecond time-ordering, UUIDv7 is an officially ratified IETF standard (RFC 9562) that maintains 100% binary compatibility with standard 16-byte UUID database columns, whereas ULID uses an informal spec and 26-character Base32 text encoding.
Is my data generated privately on my device?
Yes. All UUIDv7 generation and timestamp inspections execute 100% locally inside your browser's runtime memory using the native Web Crypto API. No identifiers or timestamps are ever transmitted across a network or saved in an external database.