What is a UUID v4 vs UUID v7
UUID v4 carries 122 random bits. It has no sequence, no clock and nothing to decode, which makes it the safest choice when you want an identifier that reveals nothing and can be minted anywhere. UUID v7 keeps 74 random bits but spends the first 48 on a Unix millisecond timestamp (plus a few bits of sub-millisecond counter), so two values created a minute apart compare in that order as strings.
The consequence shows up in an index. With random keys, every insert lands somewhere different in the B-tree: pages split, the working set grows, and write throughput falls as the table grows. With v7, inserts arrive at the right-hand edge of the tree and behave almost like an auto-increment column, while keeping the ability to generate the value on any node without coordination.
What you pay for that is information disclosure. A v7 timestamp tells anyone holding the value roughly when it was created — down to the millisecond. If that is not something you want to publish, a v4 is the right answer. Both formats are defined in RFC 9562; v4 is the older of the two, carried over from RFC 4122.
How to
- Generating keys for a table that will be indexed? Use v7 — the generator above switches version in one click.
- Publishing the identifier to users, or generating ids that must leak nothing? Use v4.
- Migrating an existing v4 key column? You cannot convert the values; new rows can use v7 while old rows keep their v4 values, since both are valid UUIDs in the same column.
Use cases
- Event and log tables, where rows are only ever appended and a time-ordered key keeps the index tight.
- Public URLs and API ids, where a v4 reveals nothing about when the resource was created.
- Multi-node writers, where both versions can be generated without a coordinator — v7 also gives you approximate ordering for free.
Compare UUID v4 vs UUID v7 with other formats
| Option | When to use |
|---|---|
UUID v4 | Random, 122 bits. Best when order does not matter. |
UUID v7 | Unix ms + random. Best for indexed keys and append-only tables. |
UUID v6 | The same ordering idea applied to the v1 layout; keeps the old 100-ns clock. |
Storage | Identical: 16 bytes, 36 characters, the same database types. |
Code examples
Generate both in JavaScript
// v4 — built in
const v4 = crypto.randomUUID();
// v7 — the uuid package
import { v7 as uuidv7 } from 'uuid';
const v7 = uuidv7(); // 019535d9-3df7-79fb-b466-fa907fa17f9e
Generate both in Python
import uuid
uuid.uuid4() # random
uuid.uuid7() # time-ordered, Python 3.14+
Read the timestamp back
import uuid
u = uuid.UUID('019535d9-3df7-79fb-b466-fa907fa17f9e')
print(u.version) # 7
# PostgreSQL 18 can do it in the query
# SELECT uuid_extract_timestamp(id) FROM events;
Frequently asked questions
Does v7 replace v4?
No. RFC 9562 defines both and neither is deprecated. v7 is a better fit for keys that live in an index; v4 remains the right choice when you do not want the creation time to be recoverable, or when you simply need an unpredictable value.
Is a v7 UUID still unique?
Yes. It spends 48 bits on time and keeps 74 random bits, and the RFC requires a monotonic counter within the same millisecond. Two values created in the same millisecond by the same process still differ, because the counter advances.
Can I migrate a v4 column to v7?
You cannot rewrite existing values into v7 form, because the v4 bits are random and contain no timestamp. What you can do is leave the old rows as they are and generate v7 for new rows: both satisfy the same uuid type, and the index benefits apply to everything inserted from now on.