Database design
Why UUID v7 Is the Better Primary Key for Your Database
April 3, 2026 · 5 min read
If you have ever used UUID v4 as a primary key and wondered why your database slows down at scale, you are not alone. UUID v4 is random by design — and randomness is the enemy of indexed sequential access. UUID v7 fixes this without giving up the benefits that made UUIDs attractive in the first place.
The problem with UUID v4 in InnoDB and similar engines
When you insert a row with a random UUID v4, the B-tree index that stores your primary key must constantly split pages to make room for new values that could land anywhere. This causes index page fragmentation, which inflates storage size and degrades read performance over time. With high-volume tables (millions of rows per day), the impact is measurable: 2–3× larger indexes and significantly more disk I/O per query.
What UUID v7 does differently
UUID v7 (defined in RFC 9562) embeds a 48-bit Unix timestamp in the most-significant bits. Newer UUIDs always sort after older ones, just like an auto-increment integer — but with 122 bits of randomness in the lower half, so you keep the collision-free, non-sequential properties that make UUIDs useful in distributed systems.
UUID v7 structure (128 bits): ├─ 48 bits: Unix timestamp (milliseconds) ├─ 4 bits: version (always 0x7) ├─ 12 bits: random ├─ 2 bits: variant (10) └─ 62 bits: random
Practical benefits at a glance
- Index-friendly inserts: New rows append to the right edge of the B-tree — no page splits, no fragmentation.
- No information leakage: Unlike auto-increment integers, a UUID does not reveal your table size or insert rate to competitors.
- Distributed-safe: Generate IDs on any node without coordination or a central sequence server.
- Time-sortable: The embedded timestamp means UUIDs sort by insert order without a separate
created_atcolumn (though you should keep one for queries).
Generating UUID v7 in your app
Most modern languages have libraries that support v7. In JavaScript (Node 20+ or browsers with Web Crypto), you can generate one yourself in under 20 lines. Our UUID Generator lets you create v7 strings instantly — useful for testing and prototyping.
Should you migrate existing tables?
If your table is small (under a few million rows) and you can tolerate a migration window, switching to v7 for new IDs is straightforward. For existing rows, a one-time backfill with new v7 IDs that preserve your original created_at timestamps is usually the right call. Running a hybrid (v4 for old rows, v7 for new) works fine but adds cognitive overhead.
The bottom line: if you are starting a new project or adding a new table to an existing database, use UUID v7. If you have an existing large table on UUID v4 that is not causing measurable problems, the migration cost may not be worth it yet — monitor your index sizes and query latency first.
Try it now — no sign-up required
Generate UUID v7 strings instantly in your browser. Zero server contact.
Open UUID Generator