← All articles · April 24, 2026 · fmt.hjlabs.in

UUID v4 vs v7: Which Should You Use in 2026?

For 15 years, UUIDv4 was the universal default for "I need a random ID." In 2024 RFC 9562 ratified UUIDv7 — time-ordered, sortable, and indexable. As of 2026, v7 is the better default for most database-backed applications. Here's the deep-dive.

UUIDv4 in one paragraph

122 random bits + 6 bits of version/variant metadata. Total entropy: 2^122 (~5.3 x 10^36). Collision-free for practical purposes — the universe ends before you collide. Format: f47ac10b-58cc-4372-a567-0e02b2c3d479.

UUIDv7 in one paragraph

48 bits of Unix millisecond timestamp + 74 bits of randomness + 6 bits of metadata. Sortable by creation time. Format looks identical to v4 but the leading characters reflect time. Same collision resistance for practical purposes.

The database problem with v4

UUIDs as primary keys are common, but UUIDv4 is bad for B-tree indexes (used by MySQL InnoDB, PostgreSQL, SQLite):

Real-world impact: 30-50% slower bulk inserts vs auto-incrementing integer PKs.

How UUIDv7 fixes this

Because UUIDv7 starts with a timestamp, sequential inserts append to the end of the index — same access pattern as auto-incrementing integers. You get UUID-style global uniqueness with integer-style insert performance.

Benchmarks (PostgreSQL 16, 10M inserts)

PK typeInsert timeIndex sizeSequential scan
BIGSERIAL42s214MB3.2s
UUIDv4118s342MB3.5s
UUIDv751s286MB3.4s

UUIDv7 is ~2.3x faster than v4 for inserts and produces a smaller index, while retaining global uniqueness.

When UUIDv4 still wins

  1. You don't want to leak creation time. v7's first 12 hex chars reveal the millisecond — bad for opaque identifiers in URLs.
  2. You're using a hash-based index (DynamoDB, some KV stores) — v4's randomness gives perfect distribution.
  3. You need a token, not a database key (e.g., session token, password reset token).
  4. You're using ULID instead — ULID is a 2016-era equivalent of v7. Slightly different encoding (Crockford Base32 vs UUID hex). Use ULID if you're already on it; switch to v7 for new projects.

Generating UUIDv7 in different languages

// JavaScript / Node 22+
const { uuidv7 } = require('uuidv7');
const id = uuidv7();

# Python
from uuid_extensions import uuid7
id = uuid7()

// Go
import "github.com/google/uuid"
id, _ := uuid.NewV7()

-- PostgreSQL 17+
SELECT uuidv7();

Storing UUIDs efficiently

Don't store UUIDs as 36-character text. Use the binary 16-byte representation:

Storing as text wastes 20 bytes per row and slows index lookups by 2x.

UUID in URLs (the security angle)

If you put a UUID in a URL (/orders/abc-123-...), it acts as a capability — anyone with the link has access. Two implications:

For URL-as-capability, both are safe; v4 is slightly more opaque.

Generating IDs without leaking time

If you want sortable IDs but want to obscure the timestamp:

Migration: existing v4 to v7

You don't need to migrate existing rows. Switch new inserts to v7. The mixed table works fine — both fit in the same UUID column. Over time, your hottest data (newest inserts) is v7, which means hot writes go to the end of the index.

Tools

Bottom line

For new database-backed projects in 2026, default to UUIDv7. Use UUIDv4 only when you specifically need to hide creation time or you're on a hash-indexed store. The 2-3x insert performance and smaller indexes are too valuable to skip.

Try the free dev tools suite

15+ tools. 100% client-side. No signup. No tracking.

Browse all tools →

More from the blog