Saturday, November 01, 2025

UUID v4 vs v7: Postgres 18

UUID v4 is a fully random, non-ordered identifier, while UUID v7 is a time-ordered identifier that includes a timestamp and random bits. UUID v4 is good for general use, but UUID v7 is better for database performance because its sequential nature reduces index fragmentation and improves write efficiency.

Why UUID7 is better than UUID4 as clustered index in RDBMS : r/programming


PostgreSQL UUID Performance: Benchmarking Random (v4) and Time-based (v7) UUIDs - DEV Community

UUIDv4: Random

UUIDv4 is the most commonly used version. It sets only two fields:
  • Version = 4 (in the 13th hex digit).
  • Variant = 10xx (in the 17th hex digit).
Everything else is pure randomness. This ensures high entropy but results in non-sequential values.

UUIDv7: Time-based

UUIDv7 was introduced to improve temporal ordering and index performance. It uses the high bits to encode a Unix timestamp in milliseconds, while the remaining bits are random to preserve uniqueness.

Comparing UUIDv4 v.s. UUIDv7 in PostgreSQL - Seven's Blog

UUIDv4 is widly used, but it’s not suitable for database primary key. Because it’s not sequential, and it’s not sortable. UUIDv7 is a new UUID version, it’s sequential and sortable. It looks interesting to use it for database primary keys.

UUIDv7 Comes to PostgreSQL 18

UUIDs were first standardized in RFC 4122 in 2005. This RFC defines 5 variants of UUIDs, of which variant 1 and 4 are the most common. The specification was later revised to add variants 6-8 in RFC 9562 which was published in May 2024 (although the first public working draft was published in 2020).

Until PostgreSQL 18, UUIDv7 was not natively supported. The built-in gen_random_uuid() function generated UUIDv4, and while the popular uuid-ossp extension added support for additional UUID variants, it was limited to the variants specified in RFC 4122.

PostgreSQL 18 adds a new function: uuidv7(), which generates UUIDv7 values. The Postgres implementation includes a 12-bit sub-millisecond timestamp fraction immediately after the timestamp (as allowed but not required by the standard). This guarantees monotonicity for all UUIDv7 values generated by the same Postgres session (same backend process).

No comments: