DEV Community

David
David

Posted on

UUID v4 vs v7: What Changed and Why It Matters

UUIDs are everywhere. Database primary keys, API request IDs, session tokens, distributed system identifiers — if you've written backend code, you've generated millions of them.

But here's a question most developers never stop to ask: which UUID version should I actually be using?

For years, UUID v4 was the default answer. Random bytes, good enough, move on. But UUID v7 landed in RFC 9562 (May 2024) and it changes the game in ways that matter for real-world systems.

Let's break it down.


UUID v4: The Random Standard

UUID v4 is pure randomness. 122 random bits, 6 bits for version and variant metadata. That's it.

f47ac10b-58cc-4372-a567-0d8b62691e10
         ^^^^                        
         version 4
Enter fullscreen mode Exit fullscreen mode

How it works:

  1. Generate 128 random bits
  2. Set version (4 bits → 0100)
  3. Set variant (2 bits → 10)
  4. Format as 8-4-4-4-12 hex string

The good:

  • Dead simple to generate
  • Statistically unique (2^122 possible values)
  • No coordination needed between systems
  • No information leakage (no timestamps, no MAC addresses)

The not-so-good:

  • Completely random = terrible for database indexing
  • No natural ordering
  • Can't extract any useful metadata
  • B-tree index fragmentation in databases

UUID v4 has served us well. But "good enough" isn't the same as "optimal."


UUID v7: Time-Ordered by Design

UUID v7 is the new kid, and it was designed specifically to fix v4's biggest weakness: sort order.

019526de-a3c0-7cc0-b2e8-4a1b3c5d7e9f
^^^^^^^^ ^^^^                        
timestamp  version 7
Enter fullscreen mode Exit fullscreen mode

How it works:

  1. Take the current Unix timestamp in milliseconds (48 bits)
  2. Set version (4 bits → 0111)
  3. Set variant (2 bits → 10)
  4. Fill remaining 62 bits with random data
  5. Format as standard UUID string

The structure:

|  48 bits   | 4 |  12 bits  | 2 |    62 bits     |
| timestamp  |ver|  rand_a   |var|    rand_b      |
Enter fullscreen mode Exit fullscreen mode

The good:

  • Naturally time-ordered (lexicographic sort = chronological sort)
  • Database-friendly: sequential inserts, minimal B-tree page splits
  • Timestamp extractable: you can read when the UUID was created
  • Still globally unique (62 random bits + millisecond timestamp)
  • Drop-in replacement: same 128-bit, same string format

The trade-offs:

  • Leaks creation time (the first 48 bits ARE the timestamp)
  • Slightly less randomness than v4 (62 vs 122 random bits)
  • Newer — not all libraries support it yet

The Database Performance Story

This is where UUID v7 really shines, and why it was created in the first place.

The Problem with v4 in Databases

When you use UUID v4 as a primary key in a B-tree indexed table (which is... most tables), every INSERT goes to a random location in the index. This causes:

  • Page splits: The B-tree constantly reorganizes
  • Cache misses: No locality of reference
  • Write amplification: More I/O per insert
  • Index bloat: Fragmented pages with wasted space

At scale, this matters. A lot.

How v7 Fixes It

Because UUID v7 values are time-ordered, new inserts always go to the end of the B-tree. This means:

  • Sequential writes: Appending, not random inserting
  • Better cache utilization: Recent data is co-located
  • Fewer page splits: The tree grows naturally
  • Smaller indexes: Less fragmentation

Benchmarks consistently show 2-10x better INSERT performance with UUID v7 vs v4 on PostgreSQL and MySQL, depending on table size and workload.


When to Use Which

Use UUID v4 when:

  • You need zero information leakage (timestamps are sensitive)
  • You're generating tokens or secrets (maximum entropy matters)
  • Ordering doesn't matter (in-memory lookups, hash maps)
  • You're working with systems that only support v4

Use UUID v7 when:

  • IDs are database primary keys (the main use case)
  • You want natural chronological ordering
  • You need to extract creation time from the ID
  • You're building distributed systems that need time-ordered events
  • You care about database performance at scale

Quick Decision Matrix

Scenario Recommendation
Database primary key v7
API request tracing v7
Session tokens v4
Event sourcing v7
Password reset tokens v4
Distributed log entries v7
Cache keys (no ordering needed) v4

Extracting the Timestamp from v7

One of v7's underrated features: you can read the creation time directly from the UUID.

function extractTimestamp(uuidV7) {
  const hex = uuidV7.replace(/-/g, '');
  const timestampHex = hex.substring(0, 12);
  const timestampMs = parseInt(timestampHex, 16);
  return new Date(timestampMs);
}

// Example
extractTimestamp('019526de-a3c0-7cc0-b2e8-4a1b3c5d7e9f');
// → 2025-02-05T...
Enter fullscreen mode Exit fullscreen mode

This is incredibly useful for debugging, auditing, and understanding data flow without extra columns or metadata.


Generating UUIDs in Practice

Node.js (v20+):

import { randomUUID } from 'crypto';
// v4 only (as of Node 22)
const id = randomUUID();

// For v7, use a library:
import { v7 as uuidv7 } from 'uuid';
const id = uuidv7();
Enter fullscreen mode Exit fullscreen mode

Python:

import uuid

# v4
uuid.uuid4()

# v7 (Python 3.14+ or uuid7 package)
from uuid_extensions import uuid7
uuid7()
Enter fullscreen mode Exit fullscreen mode

PostgreSQL:

-- v4 (built-in)
SELECT gen_random_uuid();

-- v7 (PostgreSQL 17+ or pg_uuidv7 extension)
SELECT uuid_generate_v7();
Enter fullscreen mode Exit fullscreen mode

Or just use a free online tool: createuuid.com — generates v1, v4, and v7 UUIDs instantly in your browser, with bulk generation support.


The Migration Question

"Should I migrate my existing v4 columns to v7?"

Short answer: probably not.

Existing v4 UUIDs work fine. The cost of migrating primary keys in production databases is almost never worth it. Instead:

  1. Use v7 for new tables and services
  2. Keep v4 where it already exists
  3. Let the natural lifecycle of your system handle the transition

The one exception: if you're experiencing real performance issues from UUID v4 index fragmentation at scale, and you've confirmed UUIDs are the bottleneck (not something else), then a planned migration might be worth it.


TL;DR

UUID v4 UUID v7
Introduced RFC 4122 (2005) RFC 9562 (2024)
Random bits 122 62
Time-ordered
DB performance Poor at scale Excellent
Timestamp readable
Best for Tokens, secrets Primary keys, events

UUID v7 isn't a replacement for v4 — it's the right tool for a different (and very common) job. If you're starting a new project and your UUIDs will be database primary keys, v7 is the better default.

Need to generate some UUIDs right now? Try createuuid.com — free, instant, no signup.


This is part of the Developer Tools Deep Dives series, where we explain the concepts behind common developer utilities.

Top comments (0)