PGConf.EU 2024 took place in Athens, Greece from October 22–25, 2024, gathering PostgreSQL contributors and practitioners from across Europe and beyond.
UUID v7 as a Drop-in Replacement for UUID v4
A recurring theme across multiple sessions was the transition from UUID v4 to UUID v7 for primary key generation. Speakers highlighted that the fully random nature of UUID v4 leads to index bloat and slower write performance as tables grow — a well-documented problem in high-throughput PostgreSQL deployments.
UUID v7, standardized in RFC 9562, solves this by encoding a millisecond Unix timestamp in the most significant bits. Rows inserted sequentially in time produce monotonically increasing UUIDs, which allows the B-tree index backing a primary key to grow from the right — avoiding costly page splits and keeping the index compact.
PostgreSQL 18 and the Built-in uuidv7()
One of the most anticipated announcements covered at PGConf.EU 2024 was the inclusion of a native uuidv7() function in PostgreSQL 18. Until now, teams wanting UUID v7 in PostgreSQL had to rely on community extensions such as pg_uuidv7. With a built-in implementation, the barrier to adoption drops significantly — no extension installation, no custom migration, just a standard function available out of the box.
Sessions also noted that PostgreSQL 18 will ship uuidv4() as a new alias, deprecating the older gen_random_uuid() name while maintaining full backwards compatibility.
Migration Strategies for Production Schemas
Several talks addressed the practical question of migrating existing schemas from UUID v4 to UUID v7. Key points raised:
- New tables: Simply change the column default from
gen_random_uuid()touuidv7(). Existing rows remain UUID v4; only new inserts use v7. - In-place migration: Generate a new UUID v7 for each row and update foreign key references. Feasible for smaller tables; requires careful orchestration for large datasets.
- Dual-column approach: Add a
uuid_v7column alongside the existing primary key, backfill it, then switch the application to use the new column before eventually dropping the old one. - Version detection: UUID version is encoded in bits 76–79. Applications can inspect the version nibble (
uuid & 0x0000000000000000F000000000000000) to detect v4 vs v7 rows during transition periods.
Related PostgreSQL Resources
- PostgreSQL 18 Release Notes — official documentation for the new UUID functions
- pg_uuidv7 extension — community extension for UUID v7 in PostgreSQL 17 and earlier
- RFC 9562 — Universally Unique IDentifiers — the standard defining UUID v7 structure
Frequently asked questions
Was UUID v7 discussed at PostgreSQL conferences?
Yes. PGConf.EU 2024 included sessions on UUID v7 as a replacement for UUID v4 primary keys in PostgreSQL, covering the B-tree index behaviour, the upcoming PostgreSQL 18 uuidv7() function, and practical migration steps. The PostgreSQL global events calendar lists upcoming conferences where these topics continue to be discussed.
Does PostgreSQL 18 support UUID v7 natively?
Yes. PostgreSQL 18 ships a built-in uuidv7() function that generates RFC 9562-compliant UUID v7 values directly in SQL — no extensions or application-level generation required. The values store in the existing uuid column type unchanged.
Do UUIDs hurt database index performance?
UUID v4 does — its randomness causes every insert to land at a different leaf page, leading to page splits and poor cache locality. UUID v7 embeds a millisecond timestamp so consecutive inserts cluster together, behaving like an auto-increment integer for B-tree purposes.
Does PostgreSQL 18 include a native UUID v7 function?
Yes. PostgreSQL 18 adds a built-in uuidv7() function, eliminating the need for third-party extensions like pg_uuidv7. Sessions at PGConf.EU 2024 previewed this change and showed how it aligns with the RFC 9562 standard.
Why is UUID v7 better than UUID v4 for PostgreSQL primary keys?
UUID v4 generates fully random values, causing B-tree index fragmentation as rows are inserted in random order. UUID v7 embeds a millisecond-precision Unix timestamp in the high bits, so new rows cluster near the end of the index — similar to a BIGSERIAL but globally unique.