TTKTheTextKit

UUID v4 vs v7: Differences, Format and Which One to Use

UUID v4 vs v7 explained: how each is built, how to read the timestamp in a v7, collision odds and which to pick for database keys and public IDs.

By TheTextKit TeamPublished

UUID v4 vs v7: a random v4 identifier above a v7 identifier whose first twelve characters are a timestamp

Two example UUIDs. The v4 is fully random. The v7 starts with a timestamp, shown in blue, followed by random digits.

UUID v4 is 122 random bits wrapped in a fixed layout. UUID v7 replaces the first 48 bits with the current Unix time in milliseconds and fills the rest with random bits, so its values sort by creation time. Use v7 for database primary keys that take many inserts, and v4 when an ID is public and its creation time should stay private, or when your language has no v7 yet. This guide covers how each is built, how to read the time inside a v7, the collision math, and a simple rule for choosing.

UUID v4 vs v7: the short answer

Both are 128-bit identifiers written as 36 characters. The standard that defines them is RFC 9562, published in May 2024, which obsoleted RFC 4122 and added versions 6, 7 and 8.

UUID v4UUID v7
Made fromRandom bits only48-bit Unix time in ms, then random bits
Random bits12274
Sorts by creation timeNoYes, to the millisecond
Reveals when it was madeNoYes, to the millisecond
Best forPublic IDs, quick tokens for testsDatabase primary keys, event logs
In the browsercrypto.randomUUID()No built-in function
In PostgreSQLuuidv4() or gen_random_uuid()uuidv7() (version 18 and later)

One detail worth knowing: RFC 9562 says implementations should use v7 instead of the older v1 and v6 where possible. It does not say v7 should replace v4. The choice between them is yours.

How a UUID is built

Every UUID is 16 bytes, or 32 hex digits, grouped 8-4-4-4-12 with hyphens. Two spots tell you what you are holding: the first character of the third group is the version, and the first character of the fourth group (8, 9, a or b) marks the RFC variant.

Here is a v4 and a v7. The v4 came from crypto.randomUUID(), and the v7 was built to the RFC layout for 14 October 2026, 09:30:00.123 UTC:

58334adf-46e1-4adf-9c07-f8a38c65743f   (version digit 4)
01a139bf-4a3b-734f-b6f8-e7cc807673bd   (version digit 7)

The bit layout in UUID v4 vs v7, from RFC 9562 sections 5.4 and 5.7, is the same shape with different contents:

Bit layout of UUID v4 and v7: 48 bits, 4 version bits, 12 bits, 2 variant bits and 62 bits

Two bars of 128 bits. Both split into 48, 4, 12, 2 and 62 bits. In v4 everything but the version and variant bits is random. In v7 the first 48 bits are a timestamp.

Same 128 bits, different first 48: random in v4, a timestamp in v7.

In v4, only 6 of the 128 bits are fixed (4 for the version, 2 for the variant), which leaves 122 random bits. In v7, the first 48 bits are the timestamp, the same 6 are fixed, and the remaining 74 are random.

How to read the time inside a UUID v7

Because the first 48 bits are Unix milliseconds, you can decode a v7 by hand:

  1. Remove the hyphens and take the first 12 hex digits: 01a139bf4a3b.
  2. Convert them to decimal: 1791970200123.
  3. Read that as milliseconds since 1 January 1970 UTC: 2026-10-14 09:30:00.123 UTC.
Three steps to read the time in a UUID v7: take 12 hex digits, convert to decimal, read as Unix milliseconds

Step one highlights the first 12 hex digits of a v7. Step two shows them as the decimal 1791970200123. Step three reads that as 14 October 2026, 09:30:00.123 UTC.

The example v7 decodes to 14 October 2026 at 09:30:00.123 UTC.

Paste the decimal number into the Unix Timestamp & Epoch Converter. It treats a number of 12 or more digits as milliseconds and shows the UTC date. Our guide on how to convert a Unix timestamp to a date explains the seconds versus milliseconds trap in detail.

A 48-bit millisecond counter does not run out soon. PostgreSQL's documentation puts the limit at about the year 10889.

Why v7 is easier on database indexes

A primary key index keeps its values in order. With v4, every new key lands at a random position, so inserts touch pages all over the index. With v7, the newest key is almost always the biggest one, so inserts pile up at the end, much like an auto-increment number. That is the problem RFC 9562 section 2.1 describes when it says many large applications went looking for a better time-based, sortable identifier for database keys. PostgreSQL 18, released on 25 September 2025, added uuidv7(), which its announcement says supports better caching strategies.

We ran a small seeded simulation to make the effect visible: 20,000 keys inserted one after another, counting how many landed in the newest 1% of the index.

Dot plot of where new UUID v4 and v7 keys land in a sorted index: v4 scattered, v7 all at the newest end

Two strips from oldest to newest key. The last 150 v4 inserts are scattered across the strip, 1.1 percent in the newest 1 percent. All the v7 inserts sit at the newest end, 100 percent.

A simulation of 20,000 inserts: v4 lands anywhere, v7 lands at the end.

Only 1.1% of the v4 keys landed there, which is what chance predicts. Every v7 key did. This shows where keys go, not how fast a database runs, so treat it as an illustration and measure your own workload before you migrate.

How likely is a UUID collision?

For random bits, the birthday approximation says the chance of any duplicate among n values is about n² divided by twice the number of possibilities. For v4 that is 2 to the power 122, about 5.3 followed by 36 zeros.

UUIDs generatedChance of any duplicate (v4)
1 millionabout 9.4 in 1026
1 billionabout 9.4 in 1020
1 trillionabout 9.4 in 1014
2.7 quintillionabout 50%

At a million UUIDs a second, reaching 2.7 quintillion takes roughly 86,000 years. For v7 the random part is only 74 bits, but it matters only among IDs created in the same millisecond. Generate 1,000 in one millisecond and the odds of a repeat are about 2.6 in 1017. Both are fine in practice, provided the random bits come from a cryptographically secure generator, as RFC 9562 section 6.9 recommends.

What a v7 gives away

The timestamp is the one real trade-off in UUID v4 vs v7. Anyone holding a v7 can read when the record was created, and a run of v7 values reveals how fast you create them. If an ID appears in a public URL and your growth rate or the age of an account is sensitive, use v4.

Neither version is a secret. RFC 9562 section 8 states that implementations should not assume UUIDs are hard to guess and that they must not be used as security capabilities. For a password or reset token, use the Password Generator or your framework's token function. For a fingerprint of a file or record, a hash is the right tool: see the Hash Generator and our guide to MD5 vs SHA-256.

UUID v4 vs v7: which one should you use?

Decision card: pick UUID v7 for database keys, heavy inserts and sorting; pick v4 when creation time must stay private

Two columns. v7 for database primary keys, tables with heavy inserts and sorting by creation time. v4 when creation time must stay private, when your stack has no v7 yet and for quick IDs in the browser.

A one-glance rule for choosing a UUID version.

Use v7 for primary keys on tables that take many inserts, for event and log IDs you will sort by time, and anywhere you want the ID itself to carry an approximate creation time.

Use v4 for public identifiers where creation time must stay private, for IDs generated in a browser, and when your database or language has no v7 function yet. Python added uuid.uuid7() in 3.14, and PostgreSQL added uuidv7() in 18.

Mixing is fine. A uuid column holds both, and the version digit tells you which is which. Existing v4 rows will not move, and new v7 rows will cluster at the end.

Do not expect order inside one millisecond. A plain v7 fills the rest with random bits. In our test of 1,000 values made in the same millisecond, only 507 of 999 neighbouring pairs were ascending. Python's uuid7() adds a 42-bit counter to guarantee order within a millisecond, which is the kind of detail to check in your library.

Store them as a native type. PostgreSQL's uuid type stores 128 bits, not 36 characters of text, and accepts uppercase, braces and missing hyphens on input while always printing the standard lowercase form.

Generate UUIDs in your browser

The UUID Generator makes up to 50 version 4 UUIDs at a time using crypto.randomUUID(), which MDN describes as a v4 UUID from a cryptographically secure generator, available only on HTTPS pages. Where that function is missing, the tool falls back to crypto.getRandomValues() and sets the version and variant bits itself. Nothing leaves your browser.

For v7, use the UUID v7 Generator, which makes time-ordered IDs, keeps a batch in order with the RFC's counter method and decodes the time inside any UUID. In a database, use SELECT uuidv7(); in PostgreSQL 18 or uuid.uuid7() in Python 3.14, then paste the result into the decoder or the timestamp converter to check the time inside.

Frequently asked questions

Is UUID v7 better than v4?

For database primary keys, usually yes: v7 values sort by creation time, so new rows land at the end of the index instead of all over it. For public IDs that must not reveal when something was created, v4 is the safer pick. Neither is a secret.

Can I mix v4 and v7 in the same column?

Yes. Both are valid 128-bit UUIDs in the same 8-4-4-4-12 format, so a uuid column accepts either. The version digit, the first character of the third group, tells them apart. Mixing just means old v4 rows sort randomly among the time-ordered v7 rows.

Is UUID v7 sortable?

By millisecond, yes. In a test of 1,000 plain v7 values made in the same millisecond, only 507 of 999 neighbouring pairs were in ascending order, which is chance. Order within one millisecond needs a counter, which some libraries add, such as Python 3.14.

Can you tell when a UUID v7 was created?

Yes, to the millisecond. The first 12 hex digits are a Unix timestamp in milliseconds. Drop the hyphens, convert those digits to decimal and read the result as a date. A v4 contains no time at all.

Should I use a UUID as a password or access token?

No. RFC 9562 says implementations should not assume UUIDs are hard to guess and must not use them as security capabilities. Use a purpose-built random token for secrets, and keep UUIDs for identifying records.

Pick your version before the first insert

Changing an ID format later means touching every foreign key, so settle the UUID v4 vs v7 question early. If the ID is internal and the table will grow, start with v7. If the ID is public, or your stack lacks v7, start with v4 and move on. Generate a few v4 values in the UUID Generator, and decode any v7 you meet with the timestamp converter.

Try these free tools

100% in your browser

Keep reading

All articles →