UUID v7: what it is and how to generate one
A UUID that sorts by the time it was created: that is the whole idea. Here is what the 48 timestamp bits buy you, where v7 beats v4 and where it does not, and one-line snippets to generate one in JavaScript, Python and Postgres.
What a UUID v7 is
A UUID v7 is a 128-bit identifier defined by RFC 9562, the UUID standard that replaced RFC 4122 in 2024. Its first 48 bits encode a Unix timestamp in milliseconds; the remaining bits are random. Because the timestamp sits at the front, two v7 IDs minted a millisecond apart sort in creation order with no extra column and no lookup: comparing the raw strings is enough. The layout is visible in the string, 8-4-4-4-12 hex digits, with the 7 in the third group marking the version: 018f6a2d-8c1f-7abc-9def-2f6f9c1e4b70.
RFC 9562 defines v7 alongside v6 (a reordered v1) and v8 (custom payloads). v7 is the one aimed at new databases. For how all of them relate, see the full UUID versions guide.
Why databases like v7
Random v4 primary keys scatter new rows across a B-tree index in unpredictable spots. Every insert lands on some cold page, the cache keeps missing, and at millions of rows the write cost is real. Time-ordered keys do the opposite: each insert lands near the right edge of the index, next to the values from the millisecond before, where the pages are already hot. Same uniqueness guarantee, far better insert behavior on large tables.
There is one price, and it is worth stating plainly: a v7 ID announces its creation time to anyone who can read it (see the FAQ below). For request IDs, tokens and anything that must be unguessable, stay with v4; for primary keys and event IDs, v7 is the better fit.
v4 vs v7 at a glance
| Property | v4 | v7 |
|---|---|---|
| Where the bits come from | 122 random bits | 48-bit timestamp plus random bits |
| Sorts by creation time | No | Yes |
| Reveals creation time | No | Yes, to the millisecond |
| Fits best | Tokens, request IDs, anything unguessable | Primary keys, event IDs, anything time-ordered |
When ULID still makes sense
ULID occupies the same niche: a 128-bit, time-ordered identifier that sorts lexicographically, spelled in Crockford base32 instead of hex. If your tables already hold ULIDs, nothing here forces a migration; it solves the same problem well. For new schema work, v7 has the practical edge that it is part of the UUID standard, so the UUID columns, libraries and validators you already use accept it unchanged.
Generate a UUID v7 in code:
- JavaScript:
crypto.randomUUID()makes v4 only. Install theuuidpackage (npm i uuid), thenimport { v7 } from "uuid"and callv7() - Python 3.14 or newer: the standard library has it built in,
uuid.uuid7(). For older versions, theuuid-utilspackage backports it - PostgreSQL 18 or newer:
uuidv7()is built in and works in column defaults, e.g.id uuid default uuidv7()
Generate v7 without code
The UUID Generator on this site mints v4 and v7 in bulk, up to 500 at a time, entirely in your browser. Paste existing IDs back in and it reads the version and variant, and decodes the embedded timestamp of v1, v6 and v7 IDs to UTC.
Frequently Asked Questions
Is UUID v7 sortable?
Yes, by creation time. The first 48 bits are a Unix timestamp in milliseconds, so a v7 generated later always sorts after one generated earlier, byte for byte. Within the same millisecond the order falls to the random bits, so there is no guaranteed order at that granularity.
Can I get the timestamp back out of a UUID v7?
Yes. Take the first 12 hex characters, convert them from hex to an integer, and you have the Unix epoch time in milliseconds. Feed that into any epoch converter, like the Unix Timestamp Converter on this site, to read it as a date.
Does Postgres generate UUID v7?
PostgreSQL 18 ships a built-in uuidv7() function, so a column default can mint v7 IDs directly. Older versions have no native option: either generate the ID in your application (the Python uuid module or the JavaScript uuid package both do it) or install an extension such as pg_uuidv7.