The short answer
Pick UUID v7 for new database keys, event IDs, log entries and file names that you want in chronological order. New v7 values are always larger than older ones, so they are appended to the end of an index the way an auto increment number is, while you can still create them on any server or in the browser without asking the database.
Pick UUID v4 for tokens, public identifiers where creation time is private, and systems that already use it. A v4 value leaks nothing, and for most applications that do not store millions of rows its random order costs little. Both versions are defined in RFC 9562, published in 2024, which replaced the older RFC 4122 and added versions 6, 7 and 8.
Try it here: UUID v7 Generator
Open the full tool pageHow a UUID is built
Every UUID is 128 bits written as 32 hexadecimal digits in five groups: 8-4-4-4-12, for 36 characters including hyphens. Two fields are fixed in every modern UUID. The first digit of the third group is the version, so you can read it at a glance: 4 for random, 7 for Unix time. The first digit of the fourth group is the variant and is always 8, 9, a or b for standard UUIDs.
Example v4: 9b2f4c1e-3a7d-4e8b-a5c2-0f6d1e9a3b47. Example v7: 019a2b3c-4d5e-7f60-8a1b-2c3d4e5f6a7b. In the v7 example the first 12 hex digits (019a2b3c4d5e) are the creation time in milliseconds, which is why IDs made a second apart share most of their beginning.
| Part | UUID v4 | UUID v7 |
|---|---|---|
| Total size | 128 bits | 128 bits |
| Timestamp | None | 48 bits, Unix time in milliseconds |
| Version and variant | 6 bits (version 4) | 6 bits (version 7) |
| Random bits | 122 | 74 (12 can be used as a counter) |
| Sort order | Random | By creation time |
| Reveals creation time | No | Yes, to the millisecond |
| Timestamp lasts until | Not applicable | About the year 10889 |
Why v7 is faster as a primary key
Most databases store a primary key in a B-tree index, sorted by the key. With random v4 keys, every insert lands at a random place in that tree. Once the index is bigger than memory, inserts keep reading old pages from disk, pages split half full, and the index grows larger than it needs to be. In InnoDB (MySQL and MariaDB) the table itself is stored in primary key order, so the whole table suffers, not only the index.
With v7 keys, new rows go to the right edge of the index, the hot pages stay in memory and pages fill completely. Benchmarks by database vendors and users commonly show noticeably faster inserts and smaller indexes than with v4 on large tables, though the exact gain depends on the engine, row size and hardware. Range queries such as the newest 100 orders also get cheaper, because recent rows sit next to each other.
Store UUIDs in a native 16 byte type where one exists (uuid in PostgreSQL, BINARY(16) in MySQL, uniqueidentifier in SQL Server) rather than as 36 character text. Text keys are more than twice the size and slower to compare.
Database notes: PostgreSQL, MySQL, SQL Server, .NET
- PostgreSQL: the uuid type sorts byte by byte, so v7 order is preserved. PostgreSQL 18 added a built in uuidv7() function; older versions can receive the value from the application.
- MySQL and MariaDB: store as BINARY(16) with UUID_TO_BIN(value) without the swap flag, which keeps v7 order. MySQL's own UUID() function creates version 1, not v7.
- SQL Server: uniqueidentifier compares the last group of bytes first, so v7 values are not stored in time order there. If you need sequential keys in SQL Server, NEWSEQUENTIALID() or a bigint identity is often the simpler choice.
- .NET: Guid.NewGuid() returns v4. Since .NET 9, Guid.CreateVersion7() returns v7.
- JavaScript: crypto.randomUUID() in browsers and Node.js returns v4; v7 needs a library or a small function like the one behind the generator on this page.
Collision odds in real numbers
With 122 random bits, a v4 collision is a birthday problem. You would need about 2.7 quintillion (2.7 x 10^18) UUIDs for a 50 percent chance of one duplicate, which is one billion new IDs every second for about 86 years. Faulty random generators, copied virtual machine snapshots and bugs that reuse a value are far more realistic causes of duplicates than chance.
A v7 value has fewer random bits, but they only need to be unique within the same millisecond. Even a service generating a million IDs in one millisecond is in no practical danger. Generators also keep a counter inside the millisecond, as this one does, so IDs created in a fast batch remain strictly ordered.
Always keep a unique constraint on the column anyway. It costs nothing and turns an impossible event into a clear error instead of corrupt data.
UUID vs GUID and other versions
GUID (globally unique identifier) is Microsoft's name for a UUID. It is the same 128 bit value; Windows tools usually write it in uppercase and sometimes in braces, like {3F2504E0-4F89-41D3-9A0C-0305E82C3301}. The format options in the generator (Uppercase, Hyphens, Braces) cover these styles.
Version 1 combines a timestamp with the network card address and is rarely recommended today because it can identify the machine. Version 6 is version 1 reordered to sort by time. Versions 3 and 5 are derived from a name with MD5 or SHA-1, so the same input always gives the same UUID. Version 8 is free for custom layouts. ULID is a popular non UUID format with the same idea as v7, but v7 fits every existing uuid column.
When v7 is the wrong choice
- Public IDs where the creation time is sensitive: a v7 in a URL reveals when an account, order or document was created.
- Tokens, invitation links and password reset codes: use v4 or a longer random token, never something guessable by time.
- Systems that sort or compare IDs as text with a different byte order, like SQL Server uniqueidentifier.
- Existing tables full of v4 keys: mixing versions works, but you only gain the index benefit for new rows.