Quick answer
Use v7 for database primary keys and anything you want sorted by creation time. Use v4 when the ID is public and must not reveal when it was made, or when your database prefers keys that spread writes out. Both are standard 128-bit UUIDs, so they fit the same column type and you can switch for new rows at any time.
How they differ
A UUID v4 is 122 random bits plus 6 fixed bits that mark the version and variant. Nothing in it means anything.
- Random
- Version, always 4
- Variant, 8, 9, a or b
A UUID v7 starts with a 48-bit timestamp: the number of milliseconds since 1 January 1970, UTC. The rest is random, apart from the same version and variant bits. Because the time comes first, v7 IDs made later sort after IDs made earlier.
- Timestamp, 48 bits
- Random, 74 bits
- Version, always 7
- Variant, 8, 9, a or b
| v4 | v7 | |
|---|---|---|
| Built from | 122 random bits | 48-bit time in ms, up to 74 random bits |
| Sorts by creation time | No | Yes, to the millisecond |
| Reveals when it was made | No | Yes, to anyone who decodes it |
| New rows in a B-tree index | Land anywhere | Land at the end |
| Defined in | RFC 4122 (2005), now RFC 9562 | RFC 9562 (2024) |
Both are equally unique in practice. The random part of a v7 is smaller, but it only has to be unique among IDs made in the same millisecond.
Why v7 is kinder to databases
Most databases keep a primary key index as a B-tree. A B-tree stores keys in sorted order across fixed-size pages.
With v4, each new key is random, so it belongs at a random spot in the index. The database has to find and change a different page for almost every insert. Pages fill up in the middle and split, and the whole index has to stay in memory to stay fast. On large tables this shows up as slower inserts and a bigger index.
With v7, each new key is a little larger than the last one. New entries go onto the last page, much like an auto-increment integer. The pages you are writing to stay in memory, and pages fill up neatly before a new one starts.
This matters even more in MySQL’s InnoDB, which stores the table rows themselves in primary key order. It also gives you a free bonus: ORDER BY id returns rows in roughly the order they were created.
When v4 is still the better choice
The ID is public and the creation time is private. Anyone can read the timestamp out of a v7. If your IDs show up in URLs or API responses, a v7 tells people when an account, order or document was created. Read how to get the timestamp from a UUID v7 to see how easy it is.
Your database wants writes spread out. Some distributed databases, such as Google Cloud Spanner, split tables by key range across servers. Keys that always increase send every new row to the same server. Random v4 keys spread the load.
Ordering does not matter. For small tables, cache keys, file names or message IDs that are only ever looked up exactly, v4 is simpler and supported everywhere.
A common pattern is to use both: v7 as the internal primary key, and a separate random v4 as the public ID.
Generate them in code
// v4: built into browsers and Node.js
const a = crypto.randomUUID();
// v7: npm install uuid
import { v7 } from 'uuid';
const b = v7();crypto.randomUUID() only makes v4.
import uuid
a = uuid.uuid4()
b = uuid.uuid7() # Python 3.14 and laterOn older Python, use a package such as uuid6 for v7.
SELECT gen_random_uuid(); -- v4
SELECT uuidv7(); -- v7, PostgreSQL 18 and laterBoth return the native uuid type.
var a = Guid.NewGuid(); // v4
var b = Guid.CreateVersion7(); // v7, .NET 9 and laterGood to know
You can mix them in one column
Old v4 rows and new v7 rows live happily side by side. Only the new rows get the ordering benefit.
Order inside one millisecond depends on the library
Some libraries add a counter so IDs from the same millisecond still sort in order. Others leave those bits random.
Neither one is a secret
RFC 9562 says not to assume UUIDs are hard to guess. Use a real random token for password resets and share links. See is it safe to show UUIDs in URLs?

