Generador Studio

UUID v4 vs UUID v7: Which One Should You Use as a Primary Key?

Last updated: October 8, 2026

For years "use UUID v4" was the default answer for unique identifiers. Since RFC 9562 (2024) formalized UUID v7, the right question is no longer whether to use a UUID but which version, and for what. The difference shows up mostly in the performance of write-heavy databases, and in what the identifier reveals about you.

What they share and what changes

Both versions are 128-bit identifiers with the same text format (32 hexadecimal characters with hyphens, 36 in total), and both are defined in RFC 9562, which replaces RFC 4122. Collision probability is negligible in both: in a UUID v4, with 122 random bits, you would need to generate on the order of 2.7 × 10¹⁸ identifiers to reach a 50% chance of a single collision.

What changes is the internal structure. A UUID v4 is almost entirely random: apart from a few bits that mark version and variant, the rest are cryptographically random bits. A UUID v7 starts with a 48-bit timestamp (milliseconds since January 1, 1970, the Unix epoch) followed by random bits. This makes UUID v7 values generated at different times sort chronologically when compared as strings or bytes.

Why it matters for databases

Most database indexes are B-trees. When you insert a row with a random identifier (v4), the new value lands at an arbitrary position in the index. On large tables that causes page splits, fragmentation and more disk or cache reads, because each insert touches a different part of the tree. In engines where the primary key defines the physical order of the table (such as InnoDB in MySQL) the effect is even more pronounced.

With UUID v7 new inserts carry an increasing time prefix, so they land near the end of the index, like an auto-incrementing integer. You keep the advantage of generating the identifier in the application without querying the database, and you avoid much of the write cost of pure randomness. The difference is negligible on small tables and starts to show when the table is large and receives many writes.

The trade-off: v7 reveals when it was created

Because the first 48 bits of a UUID v7 are the creation time, anyone who sees the identifier can extract when it was generated, to the millisecond. This usually doesn't matter, but it can be a problem if the identifier is public and you don't want to reveal when a record was created, or if someone could infer your signup or order volume by comparing identifiers over time.

A UUID v4 reveals none of that. That is why v4 is still preferred for identifiers exposed outward that must be opaque: tokens, invite links, API keys, session identifiers. It is also worth remembering that an identifier is not a secret by itself: for security tokens the source of randomness must be cryptographically secure, which crypto.randomUUID() in the browser already is.

Current support

PostgreSQL 18, released in late September 2025, includes a native uuidv7() function and lets you extract a UUID's timestamp with uuid_extract_timestamp(). Python 3.14 added uuid.uuid7() to its standard module, and the npm uuid package also supports version 7. On older database and language versions you can generate them with a library or an extension.

One point to note in the browser: crypto.randomUUID() always generates UUID v4. If you need v7 on the client you need a library or an implementation following the RFC. And whichever version you use, store the UUID in your database's native type (uuid in PostgreSQL, BINARY(16) in MySQL) rather than as text: it is 16 bytes versus 36 characters, and indexes are much more compact.

A practical rule for choosing

If the identifier is a primary key on a write-heavy table, or you want to sort by creation without an extra column, choose UUID v7. If the identifier is publicly exposed and must be opaque, or creation time must not leak, choose UUID v4. If the table is small or low-write, either works and the decision isn't important.

One honest caveat: UUID v7 ordering is per millisecond. Two identifiers generated in the same millisecond, or on different machines with slightly skewed clocks, are not guaranteed to be in strict order unless the implementation includes a monotonic counter. To sort by creation with certainty, keep a date column alongside the identifier.

Related generators

Frequently asked questions

Can I mix UUID v4 and v7 in the same table?
Technically yes, since both are valid 128-bit UUIDs. But mixing erodes the ordering benefit of v7, because the v4 values land at random positions in the index. The usual approach is one version per table.
Is UUID v7 more secure than v4?
No. It is about how data is organized, not about security. In fact v7 has fewer random bits (74 versus 122) and reveals the creation time, so for tokens or sensitive identifiers v4 is the better choice.
Is it still valid to use UUID v4 as a primary key?
Yes. For small or low-write tables the performance difference is irrelevant, and v4 remains the most widely supported and understood version across the ecosystem.
Is an auto-incrementing integer better?
In a single database it is usually the most compact and fastest. UUIDs win when you need to generate identifiers without querying the database, merge data from multiple systems, or avoid exposing how many records you have.
Which version does this site’s UUID generator create?
UUID v4, using crypto.randomUUID() with a cryptographically secure source. It is the appropriate version for public identifiers, tokens and test identifiers.

Ver esta guía en español →