UUID v4 is fully random, while UUID v7 embeds a Unix millisecond timestamp in its first bits, so IDs generated later always sort after earlier ones. That single difference is why teams comparing UUID v7 vs v4 are switching: v7 keeps globally unique IDs but makes them time-ordered, which plays much nicer with database indexes. If you insert millions of rows, v7 keeps new keys clustered together instead of scattering them randomly across your B-tree.
Content Table
The core difference in one look
Both are 128-bit values that look identical when written out (32 hex characters with dashes), and both are standardized in RFC 9562, which replaced the older RFC 4122 in 2024. The difference is what fills those bits.
| Property | UUID v4 | UUID v7 |
|---|---|---|
| Data source | 122 random bits | 48-bit timestamp + random bits |
| Sortable by creation time | No | Yes |
| Reveals creation time | No | Yes (millisecond precision) |
| Collision risk | Extremely low | Extremely low |
| Best for DB primary keys | Fair | Excellent |
How the UUID v7 timestamp works
A v7 UUID packs a 48-bit Unix timestamp in milliseconds into the leading bits, followed by version and variant markers, then fills the remaining space with random data. Because the timestamp sits at the front, lexical (string) sorting matches chronological order automatically.
Here is the rough layout of a v7 value:
- Bits 0-47: Unix time in milliseconds since the 1970 epoch
- Bits 48-51: version number (0111 = 7)
- Bits 52-63: random data (or an optional sub-millisecond counter)
- Bits 64-65: variant marker
- Bits 66-127: random data for uniqueness
That 48-bit millisecond field is the same kind of value you would get from a standard Unix timestamp. If you want to understand how those epoch values map back to real dates, our guide to converting Unix timestamps to dates walks through the exact math. The 48-bit range comfortably covers dates well past the year 10000, so you will not hit the classic Year 2038 problem that plagues 32-bit time fields.
Why time-ordering matters for databases
Random v4 keys scatter inserts all over a B-tree index. Every new row can land on a different page, forcing the database to keep reshuffling and reloading pages that were already flushed from cache. This causes page splits, index fragmentation, and write amplification, especially on high-insert tables.
Time-ordered UUIDs fix this because new values are always slightly larger than the last one:
- Sequential inserts: new rows append near the "right edge" of the index instead of jumping around
- Better cache behavior: recently used index pages stay hot in memory
- Less fragmentation: fewer page splits mean smaller, tidier indexes
- Free chronological sorting: ordering by primary key is effectively ordering by creation time
Postgres, MySQL, and SQLite all benefit here, and it is one of the strongest arguments in the ongoing debate about how to store time data in databases. This performance angle is also central to the ULID vs UUID discussion, since ULIDs solved the same sortability problem years before v7 was standardized.
When v4 is still the right pick
Time-ordered UUIDs are not automatically better for every job. Stick with v4 when:
- You need unpredictability: session tokens, password reset links, or API keys should not reveal when they were made or hint at ordering.
- The ID is public-facing: exposing creation timestamps in shareable URLs can leak business metrics (how many signups per hour, for example).
- Ordering does not matter: lookup tables or configuration rows that rarely change gain nothing from clustering.
For anything security-sensitive, the pure randomness of v4 is a feature, not a weakness. The 122 random bits make it computationally infeasible to guess a valid value.
Switching from v4 to v7
You do not have to rewrite everything at once. Both versions share the same 128-bit format and the same column type (usually
UUID
or a 16-byte binary), so they coexist in one table without schema changes.
- Change the generator, not the storage: point new inserts at a v7 function; old v4 rows stay valid.
-
Check library support:
most modern languages ship v7 generators (Python's
uuid6backports, Java, .NET 9, Go libraries, and Node crypto add-ons). - Don't rely on strict monotonicity: within the same millisecond, ordering depends on the random or counter bits, so treat v7 as roughly ordered, not perfectly sequential.
- Reindex if needed: existing fragmented v4 indexes won't magically heal, but new v7 inserts will keep the tail tidy.
Generate v4 and v7 UUIDs in seconds
Testing the uuid v7 vs v4 difference for yourself is the fastest way to decide. Our free UUID generator creates both versions instantly so you can compare their structure side by side.
Generate a UUID →
Yes. Even though v7 spends 48 bits on a timestamp, it still fills the rest with random data. Within a single millisecond you get enough random bits that collisions are astronomically unlikely, matching v4's practical uniqueness for almost every real workload.
Yes. The first 48 bits are a Unix millisecond timestamp, so you can read the exact creation time straight from the value without a database lookup. This is handy for debugging but also means the ID reveals timing, which matters for privacy-sensitive use cases.
For insert-heavy tables, yes. Time-ordered keys append near the edge of the B-tree index instead of scattering randomly like v4. That reduces page splits, index fragmentation, and cache misses, giving you faster writes and tidier indexes on Postgres, MySQL, and similar systems.
Both embed a millisecond timestamp for sortability. ULID uses a compact 26-character Base32 encoding, while v7 keeps the standard 36-character UUID format and is defined in RFC 9562. If you already rely on the UUID ecosystem, v7 fits in without changing your column types.
No. Both are 128-bit values that use the same column type and the same 36-character text representation. You can mix v4 and v7 in one table with no schema changes, which makes gradual migration painless: just switch your generator for new records.