UUID v4 vs v7: Which One Actually Sorts

Check whether v4 or v7 gives you chronological order for an event stream or message log, and what the timestamp encoding actually looks like.

ZERO UPLOAD · ALL LOCAL
  1. UUID v1, v4, and v7 are generated automatically on load. Click Regenerate All to get a fresh set at any time.
  2. Use the format toggle to switch between Standard, UPPERCASE, No Hyphens, Braces, and URN display formats. The format applies to all three versions at once.
  3. Click Copy next to any UUID to copy it to the clipboard in the currently selected display format.

What to look for

  • v7 only
  • 48 bits (first 6 bytes)
  • 122 of 128

v7's leading 48 bits are why it sorts in creation order; v4's 122 random bits give it no natural order at all.

FORMAT
V1 Time-based
V4 Random
V7 Time-ordered

UUID v4 vs v7: Which One Sorts Chronologically

Two UUIDs generated a second apart should, in a lot of systems, come back out in that same order when you query them. Whether that happens depends entirely on which version generated them, not on anything you configure at the database layer. UUID v4 gives you no ordering guarantee at all; UUID v7 gives you one by design. If your event stream, message log, or audit trail needs to replay in the order things actually happened, this is the one property worth checking before you pick a generator.

Why v4 UUIDs sort in no meaningful order

UUID v4 dedicates 122 of its 128 bits to a cryptographically random source, leaving no structural relationship between one generated value and the next.1 Sorting a column of v4 UUIDs alphabetically, or by byte value, produces an order that has nothing to do with when each row was created; it is effectively as random as the bits themselves, a pattern well documented in database engineering writeups on random primary keys.2

For a use case where ordering never matters, that randomness is a feature, not a limitation: it guarantees no two clients can predict or coordinate on the next identifier, and it spreads generated values evenly across the entire 128-bit space. The moment your application needs to replay events in the order they happened, though, a v4 UUID column gives you nothing to sort on.

What you would need instead to recover order from v4 alone

Recovering chronological order from a table keyed on v4 UUIDs means adding a separate timestamp column and sorting on that instead of the primary key, since the identifier itself carries no time information. That works, but it is an extra column, an extra index, and one more place a write can disagree with the value it is supposed to represent.

Retrofitting that column onto an existing table also means backfilling a creation time for every row that predates the change, since the identifier itself gives you nothing to derive one from after the fact. A new table avoids that backfill entirely by picking v7 from the start, which is one more reason the version decision is easier to make early than to correct later.

How v7's timestamp prefix produces real chronological order

UUID v7 places a 48-bit Unix millisecond timestamp in the first six bytes of the value, followed by four version bits, then a run of random and variant bits filling the rest.1 Because the timestamp occupies the most significant bits, comparing two v7 values as plain strings, or as raw byte arrays, produces the same order as comparing their creation times directly, the monotonically ascending, lexically sortable behavior the version was specifically designed to provide.3

Two v7 UUIDs generated within the same millisecond share an identical timestamp prefix, so their relative order within that millisecond falls back to the random bits that follow. For a message log or event stream generating far fewer than a thousand entries per millisecond, that fallback almost never produces a visibly wrong order, and even when it does, the gap is a single millisecond, not the effectively random spread a v4 column would produce.

Confirming sort behavior on this page directly

You can see this difference directly without touching a database. Generate a batch here, wait a few seconds, and generate a second batch: the V7 row's leading characters shift forward in a predictable direction each time, while the V4 row's leading characters show no relationship at all between the two batches. That is the entire chronological-sort claim, visible in twelve characters.

When you actually need this property

An event stream that replays entries in creation order, an audit trail that a compliance review reads chronologically, or a message queue that processes entries roughly in the order they arrived, all benefit directly from a v7 identifier, because the sort order and the creation order are the same thing.

One caveat worth knowing: the timestamp comes from the generating client's own clock, not from a central authority, so values generated on two different machines with meaningfully skewed clocks can sort slightly out of true chronological order. For a browser-based tool generating one value at a time, that skew is rarely large enough to matter, but a distributed system generating v7 values across many servers should keep those clocks synchronized if strict cross-machine ordering matters.

Verifying the sort order yourself

None of this requires trusting either version blindly. Generate a handful of each here, paste them into a spreadsheet, and sort the column yourself; the v7 rows will land in generation order and the v4 rows will not, which is a faster way to confirm the property than reading about it secondhand.

Repeating that check across a few separate batches, spaced a few seconds apart, makes the pattern even clearer: each new v7 batch sorts after the one before it, while a freshly generated v4 batch lands in no particular position relative to the others. That direct comparison is a more convincing demonstration than any explanation of bit layout, since it shows the property doing exactly what the specification promises rather than asking you to trust a description of it.

When to use this

Reach for v7 whenever the reading side of your system, an event stream, message log, or audit trail, needs entries to come back in the order they were created without a separate timestamp column doing the sorting.

Examples

Two identifiers generated one second apart

Before
Before: click Regenerate All, note the V4 and V7 values, wait a second, then click Regenerate All again.
After
The second V7 value's leading 12 characters are numerically greater than the first, matching the one-second gap. The second V4 value shares no such relationship with the first; comparing the two tells you nothing about which one came later.

An event log that needs to replay in creation order

Before
Before: the log table's id column is populated with UUID v4 values and a separate created_at TIMESTAMP column.
After
Switching the generator to produce v7 values lets a plain ORDER BY id return the same order as ORDER BY created_at, so the timestamp column becomes redundant for read-path ordering, though many teams keep it anyway for readability.
Sources
  1. 1.

    K. Davis, B. Peabody, P. Leach, "Universally Unique IDentifiers (UUIDs)," RFC 9562, IETF, May 2024. https://www.rfc-editor.org/rfc/rfc9562.html

  2. 2.

    Andy Atkinson, "Avoid UUID Version 4 Primary Keys (for Postgres)," andyatkinson.com, 2025. https://andyatkinson.com/avoid-uuid-version-4-primary-keys

  3. 3.

    "Universally Unique Identifier," Wikipedia, accessed August 2026. https://en.wikipedia.org/wiki/Universally_unique_identifier

FAQ