UUID v4 vs v7: which version should you use?
UUID v4 or v7? Differences, pros and cons and which version is the better fit as a database primary key today.
UUIDs (Universally Unique Identifiers) are 128-bit values used everywhere as primary keys, trace IDs and idempotency keys. v4 was the default for a long time — v7 is now displacing it for good reasons. This article explains why.
UUID versions at a glance
- v1 — timestamp + MAC address. Sortable but leaks hardware info. Rare today.
- v3 — MD5 hash of a name. Deterministic, but MD5 is outdated.
- v4 — 122 bits of randomness. Long-time default.
- v5 — SHA-1 hash of a name. Like v3, better hash.
- v7 — Unix timestamp in milliseconds + randomness. Standardized in 2024 via RFC 9562.
UUID v4 – random
v4 is 122 bits of cryptographic randomness plus 6 bits for version and variant. Example: 550e8400-e29b-41d4-a716-446655440000.
Pros
- Trivial to generate, built into every language.
- Collision probability so low it can be ignored in practice.
- Reveals nothing — not even the order of creation.
Cons
The big problem: poor index performance. B-tree indexes (PostgreSQL, MySQL/InnoDB) work best when new values append at the end. With v4, inserts land randomly across the tree, causing "page splits" and bad cache locality. On large tables this shows up as 2–10x slower inserts and larger indexes.
UUID v7 – time-ordered
The first 48 bits are a Unix timestamp in milliseconds, the rest is randomness:
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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+Pros
- Sortable by creation time — both lexicographically and binary.
- B-tree friendly: inserts land at the end, no splitting.
- Creation time readable (millisecond precision) — handy for debugging.
- Replaces ULID, KSUID and Snowflake with a standards-compliant alternative.
Cons
- Creation time is visible — no good for tokens or "unguessable" IDs.
- Clock skew between servers can scramble the ordering slightly.
v4 vs v7 comparison
| Property | UUID v4 | UUID v7 |
|---|---|---|
| Uniqueness | Very high (122 random bits) | Very high (74 random bits + timestamp) |
| Sortable | No | Yes, by creation time |
| B-tree index performance | Bad (random inserts) | Excellent (append-only) |
| Privacy / unguessability | Fully opaque | Creation time visible |
| Collision risk | Effectively zero | Effectively zero |
When to use v4 vs v7
Today's default: v7 — especially for database primary keys, event IDs, anything that benefits from chronological ordering. The performance gains are real and measurable.
Use v4 when:
- the ID is exposed externally and creation order is sensitive (reservation IDs, coupon codes),
- you don't want to leak when a record was created,
- you need token-like values that must not be guessable.
Tooling and migration
- PostgreSQL 18 ships a built-in
uuidv7()function. - Node.js:
uuid@10+(npm) providesuuid.v7(). - Python:
uuid_utils, or natively from Python 3.14. - Java:
java.util.UUIDdoesn't ship it — use libraries likeuuid-creator. - Browsers:
crypto.randomUUID()returns v4. v7 currently needs a polyfill.
Use our UUID generator to create and compare both variants directly.