Definition

A time-ordered UUID is any UUID format that places the timestamp in the most significant bits so that lexicographic string comparison matches creation-time order. UUID v7, defined in RFC 9562 (May 2024), is the current IETF-standardised time-ordered UUID format.

UUID v1 and UUID v6 are older time-ordered formats — both are deprecated by RFC 9562 in favour of UUID v7.

The three time-based UUID versions

UUID v1 (deprecated)

UUID v1 encodes a 60-bit timestamp counting 100-nanosecond intervals since the Gregorian calendar epoch (1582-10-15 00:00:00 UTC). The timestamp is split across three fields in the standard 8-4-4-4-12 layout:

time_low        (32 bits, least significant timestamp bits) — position 0–7
time_mid        (16 bits, middle timestamp bits)           — position 9–12
time_hi_version (12 bits, most significant timestamp bits) — position 14–17

The timestamp low bits appear first, which means sorting UUID v1 strings does not give creation order. UUID v1 also embeds the generator’s MAC address, creating a privacy concern — IP and MAC address can be extracted from any v1 UUID. RFC 9562 deprecates UUID v1.

UUID v6 (deprecated)

UUID v6 reorders the timestamp fields to enable lexicographic sorting:

time_high_and_mid (48 bits, most significant timestamp first) — position 0–11
version           (4 bits)                                    — position 13
time_low          (12 bits)                                   — position 14–17

UUID v6 sorts correctly as a string — earlier UUIDs compare as less than later ones. However, it still uses the 1582-epoch Gregorian timestamp, which is unfamiliar to developers accustomed to Unix timestamps. RFC 9562 deprecates UUID v6 alongside v1.

UUID v7 uses a 48-bit Unix millisecond timestamp (standard Unix epoch, zero = 1970-01-01T00:00:00Z):

unix_ts_ms  (48 bits, milliseconds since Unix epoch) — positions 0–11
ver         (4 bits, = 7)                            — position 13
rand_a      (12 bits, random or monotonic counter)   — positions 14–17
var         (2 bits, = 10)                           — position 19
rand_b      (62 bits, random)                        — positions 20–35

UUID v7 sorts correctly, uses a familiar epoch, discloses only creation time (not MAC address), and is compatible with the PostgreSQL uuid column type, MySQL CHAR(36) UUID columns, and all major UUID libraries.

Why time ordering matters for databases

A B-tree index stores values in sorted order for efficient range scans. When inserting UUID v4 primary keys, each new value lands at a random position in the sorted order — roughly half of all index pages must split to accommodate new entries. At scale (millions of rows), this causes:

UUID v7 inserts always append to the end of the index (new timestamps are always larger than existing ones), matching the B-tree access pattern of auto-increment integers. The PostgreSQL B-tree implementation documentation explains fill factor and the cost of page splits in detail.

Extracting the timestamp

From any UUID v7, extract the creation timestamp:

// JavaScript
function timestampFromV7(uuid) {
  const hex = uuid.replace(/-/g, '').slice(0, 12);
  return new Date(parseInt(hex, 16));
}

timestampFromV7('019236a7-b4f2-7000-8d3e-9c1a2b3d4e5f');
// → Date: 2026-09-25T16:00:00.000Z
# Python
import uuid as _uuid

def timestamp_from_v7(uuid_str: str) -> float:
    u = _uuid.UUID(uuid_str)
    # Standard library uuid.UUID does not expose v7 timestamp directly
    ts_ms = int(uuid_str.replace('-', '')[:12], 16)
    return ts_ms / 1000  # Unix seconds

# Python 3.13+
u = _uuid.UUID('019236a7-b4f2-7000-8d3e-9c1a2b3d4e5f')
# u.time gives the Gregorian timestamp for v1; for v7 parse manually

In PostgreSQL 18, the built-in function handles extraction:

SELECT uuid_extract_timestamp('019236a7-b4f2-7000-8d3e-9c1a2b3d4e5f');
-- Returns: 2026-09-25 16:00:00+00

Documented in the PostgreSQL 18 UUID functions reference.

External references

Frequently asked questions

What is a time-ordered UUID and why does it matter?

A time-ordered UUID embeds a timestamp in its most significant bits so that sorting UUID strings lexicographically produces the same sequence as sorting by creation time. This matters for database index performance: B-tree indexes on UUID v7 primary keys experience minimal page splits because new values always land at the end of the index. UUID v4's random bits cause every insert to land at a random position, fragmenting the index at scale. The property is defined in RFC 9562 §5.7.

What is the difference between UUID v1, v6, and v7 time ordering?

UUID v1 encodes a 60-bit Gregorian timestamp (100-nanosecond intervals since 1582-10-15) but splits it across three fields in a non-lexicographic order — the low timestamp bits appear first, so v1 UUIDs do not sort by creation time as strings. UUID v6 fixes this by reordering the timestamp fields for lexicographic sortability but uses the same 1582-epoch timestamp. UUID v7 uses a Unix millisecond timestamp (standard Unix epoch, 48 bits) which is simpler to work with and natively sortable. RFC 9562 deprecates v1 and v6 in favour of v7.

How do I generate a time-ordered UUID v7 in JavaScript?

Use the uuid npm package: import { v7 as uuidv7 } from 'uuid'; const id = uuidv7();. The browser's built-in crypto.randomUUID() only generates UUID v4 — it does not support v7. Node.js 20+ also lacks a native v7 implementation, so the uuid package is necessary for time-ordered UUIDs in JavaScript environments.