Use version 7 for database keys and version 4 when the creation time must not show. Both are 128 bits with the same text form and the same 6 bits set aside for version and variant; they differ in what fills the other 122.
The layouts
RFC 9562 defines version 4 (section 5.4) as 122 random bits. Version 7 (section 5.7) starts with 48 bits of Unix milliseconds (t), then the version, 12 bits called rand_a (a), the variant and 62 bits of rand_b (b). V is the digit holding the variant, 8 to b:
v4 rrrrrrrr-rrrr-4rrr-Vrrr-rrrrrrrrrrrr
v7 tttttttt-tttt-7aaa-Vbbb-bbbbbbbbbbbb
The tool’s core, given the same 48 random bytes twice, once for version 4 and once for version 7 with the clock fixed at 2026-10-14T23:54:51.446Z:
v4 ebcdd201-c41e-4139-be9d-3aded876abdf
b30dc3bf-2f23-4d7d-b459-87077435301a
715db00a-b1ff-4b8c-ac8b-3508b72a9618
v7 01a13cd7-16b6-7bcd-be9d-3aded876abdf
01a13cd7-16b6-7bce-b459-87077435301a
01a13cd7-16b6-7bcf-ac8b-3508b72a9618
The last 16 digits match: version 7 keeps those random bits and puts the time in front. In rand_a the tool writes a counter (bcd, bce, bcf) so a batch from one millisecond still sorts in order. The tool below starts on version 7 with three UUIDs, made from your browser’s bytes and clock instead of these.
Sort order
Version 7 sorts by creation time, as text and as bytes; version 4 sorts at random. In Python 3.14, a thousand of each:
v4 = [uuid.uuid4() for _ in range(1000)]
v7 = [uuid.uuid7() for _ in range(1000)]
print(v4 == sorted(v4), v7 == sorted(v7))
False True
That order makes version 7 the better primary key: new rows go at the right edge of a B-tree index, not on random pages. On PostgreSQL 18, a million uuidv7() keys built a 30 MB index against 38 MB for uuidv4().
Within one millisecond the generator decides: Python 3.14 uses a 42-bit counter, PostgreSQL 18 a sub-millisecond clock fraction, this tool a 12-bit counter. Across machines, the order is only as good as their clocks.
What each gives away
A version 7 UUID tells anyone who sees it when it was made, to the millisecond: paste one into Decode, or use uuid_extract_timestamp() in PostgreSQL 17+ or .time in Python 3.14. A public ID in a URL then dates the account or order behind it. Version 4 shows nothing.
Neither is a secret: RFC 9562 section 8 says not to assume UUIDs are hard to guess, so don’t use either as an access token.
Where to get each
- JavaScript:
crypto.randomUUID()for version 4; theuuidpackage’sv7()(version 10 and later) for version 7. - Python:
uuid.uuid4();uuid.uuid7()from Python 3.14. - PostgreSQL:
gen_random_uuid()from PostgreSQL 13;uuidv7()from PostgreSQL 18.
A uuid column holds both, so a table can switch its default from version 4 to version 7 without touching old rows.