NetLabToolsNetLabTools

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.

6 min read

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

PropertyUUID v4UUID v7
UniquenessVery high (122 random bits)Very high (74 random bits + timestamp)
SortableNoYes, by creation time
B-tree index performanceBad (random inserts)Excellent (append-only)
Privacy / unguessabilityFully opaqueCreation time visible
Collision riskEffectively zeroEffectively 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) provides uuid.v7().
  • Python: uuid_utils, or natively from Python 3.14.
  • Java: java.util.UUID doesn't ship it — use libraries like uuid-creator.
  • Browsers: crypto.randomUUID() returns v4. v7 currently needs a polyfill.

Use our UUID generator to create and compare both variants directly.