If you've written backend code, you've generated millions of UUIDs. Database primary keys, API request IDs, session tokens, distributed system identifiers — they're everywhere.
But here's a question most developers never stop to ask: which UUID version should you actually be using?
For years the default answer was v4. Random bytes, good enough, move on. Then UUID v7 landed in RFC 9562 in May 2024, and it changes the math in ways that matter at scale. Let's settle it.
UUID v4: The Random Standard
UUID v4 is pure randomness — 122 random bits with 6 bits reserved for version and variant metadata.
f47ac10b-58cc-4372-a567-0d8b62691e10
^^^^
version 4
Strengths: dead simple to generate, statistically unique (2122 values), needs zero coordination between systems, and leaks no information.
Weakness: completely random means terrible for database indexing. No natural ordering, no extractable metadata, and chronic B-tree fragmentation.
UUID v7: Time-Ordered by Design
UUID v7 was built specifically to fix v4's sort-order problem.
019526de-a3c0-7cc0-b2e8-4a1b3c5d7e9f ^^^^^^^^ ^^^^ timestamp version 7
The layout:
| 48 bits | 4 | 12 bits | 2 | 62 bits | | timestamp |ver| rand_a |var| rand_b |
The first 48 bits are the current Unix timestamp in milliseconds. The remaining 62 bits are random. Because the timestamp leads, v7 values come out naturally time-ordered. Lexicographic sort equals chronological sort.
The Database Performance Story
The problem with v4 in databases
When you use UUID v4 as a primary key in a B-tree-indexed table, every INSERT hits a random index page, causing page splits, cache misses, write amplification, and index bloat.
How v7 fixes it
Time-ordered values mean new rows append to the end of the B-tree: sequential writes, better cache utilization, fewer page splits, smaller indexes. Benchmarks show 2–10x better INSERT performance with v7 on PostgreSQL and MySQL. See RFC 9562 for detailed performance analysis.
Generate v4 and v7 side by side with our UUID Generator.
Extracting the Timestamp
Read the creation time directly from the ID:
function extractTimestamp(uuidV7) {
const hex = uuidV7.replace(/-/g, '');
return new Date(parseInt(hex.substring(0, 12), 16));
}
That's free auditing — useful for debugging distributed event flows without an extra column.
Generating UUIDs in Practice
Node.js: import { v7 as uuidv7 } from 'uuid';
Python: from uuid_extensions import uuid7
PostgreSQL 17+: SELECT uuid_generate_v7();
For quick one-offs, use our UUID Generator — v4 and v7 in bulk, one-click copy.
When to Use Which
| Scenario | Recommendation |
|---|---|
| Database primary key | v7 |
| API request tracing | v7 |
| Event sourcing | v7 |
| Session tokens | v4 |
| Password reset tokens | v4 |
| Share links | v4 |
Rule of thumb: indexed ID → v7. Secret or token → v4.
Should You Migrate Existing v4 Columns?
No. Leave v4 where it lives. Use v7 for new tables and let the system age into it naturally. See our What is UUID v7 article for more on the v7 standard.
TL;DR
| v4 | v7 | |
|---|---|---|
| Standard | RFC 4122 (2005) | RFC 9562 (2024) |
| Time-ordered | ❌ | ✅ |
| DB performance | Poor at scale | Excellent |
| Best for | Tokens, secrets | Primary keys, events |
If you're starting a new project and your IDs will be primary keys, v7 is the better default.