PGConf.dev is the annual international PostgreSQL developer conference, drawing core contributors, extension authors, and enterprise PostgreSQL users. The 2025 edition included dedicated sessions on the UUID v7 integration landing in PostgreSQL 18, covering the implementation of uuidv7(), the decision to add uuid_extract_timestamp(), and measured B-tree index performance data comparing UUID v4, UUID v7, and BIGSERIAL primary keys at scale. This page summarises the key technical points for developers planning migrations.

The PostgreSQL 18 UUID v7 addition

The core patch adding uuidv7() to PostgreSQL 18 was discussed in depth. Key design decisions covered at the conference:

The full function reference is in the PostgreSQL 18 UUID functions documentation.

Index performance data

Conference presentations included B-tree benchmark data comparing three primary key strategies on a standard PostgreSQL 18 instance with 8 GB RAM and SSD storage:

Primary key1M rows insert time10M rows insert timeIndex size (10M rows)
BIGSERIAL4.2s41s214 MB
UUID v74.8s47s298 MB
UUID v47.1s148s312 MB

UUID v7 insert performance is within 15% of BIGSERIAL. UUID v4 degrades significantly at 10M rows due to index fragmentation — a well-understood consequence of random inserts into a B-tree documented in the PostgreSQL B-tree implementation guide.

Extension path for PostgreSQL 14–17

For installations that cannot upgrade to PostgreSQL 18 immediately, the pg_uuidv7 extension provides the same uuidv7() function. Install via:

CREATE EXTENSION pg_uuidv7;

-- Use as a column default
CREATE TABLE orders (
  id         uuid PRIMARY KEY DEFAULT uuidv7(),
  created_at timestamptz NOT NULL DEFAULT now()
);

The extension was presented as a migration bridge — the function signature is identical to PostgreSQL 18’s native implementation, so removing the extension and relying on the built-in function after upgrading requires no application changes.

Migration from SERIAL to UUID v7

A full session covered the migration pattern used by a PostgreSQL-backed SaaS company migrating from BIGSERIAL primary keys to UUID v7:

-- Step 1: Add UUID v7 column alongside existing integer PK
ALTER TABLE orders ADD COLUMN uuid_id uuid DEFAULT uuidv7() NOT NULL;

-- Step 2: Backfill existing rows (generate UUIDs with synthetic timestamps)
-- (Done in batches to avoid lock contention)
UPDATE orders SET uuid_id = uuidv7() WHERE uuid_id IS NULL;

-- Step 3: Add unique constraint, verify FK references
ALTER TABLE orders ADD CONSTRAINT orders_uuid_id_key UNIQUE (uuid_id);

-- Step 4: Swap application to use uuid_id as PK, drop integer PK
ALTER TABLE orders DROP CONSTRAINT orders_pkey;
ALTER TABLE orders ADD CONSTRAINT orders_pkey PRIMARY KEY USING INDEX orders_uuid_id_key;

The PostgreSQL ALTER TABLE documentation covers constraint management during live migrations.

UUID v7 with BRIN indexes

An alternative to B-tree for time-range queries on append-heavy tables: BRIN (Block Range Index) indexes work naturally with UUID v7 because the values are time-ordered and therefore spatially correlated with physical storage location. A BRIN index on a UUID v7 primary key column can support efficient WHERE id > $threshold queries with a tiny index footprint — appropriate for large event log tables. The PostgreSQL BRIN index documentation covers the spatial correlation requirement.

Further reading

External references

Frequently asked questions

What UUID v7 support did PostgreSQL 18 introduce?

PostgreSQL 18 ships three new functions: uuidv7() generates a time-ordered UUID v7, uuidv4() generates UUID v4 (equivalent to gen_random_uuid()), and uuid_extract_timestamp() extracts the embedded timestamp from a UUID v7 value. Earlier versions can use the pg_uuidv7 extension for the same functionality.

How much faster are UUID v7 inserts than UUID v4 in PostgreSQL?

Benchmark results presented at PostgreSQL conferences show UUID v7 insert throughput approaching BIGSERIAL performance at scale — typically 3–5× faster than UUID v4 at 10 million rows due to reduced B-tree page splits. UUID v4 generates random positions in the index on every insert, causing frequent page splits and cache misses. See the PostgreSQL B-tree implementation documentation and the UUID v7 performance benchmarks page.

Can I use uuidv7() as a column default in older PostgreSQL versions?

Not natively — uuidv7() requires PostgreSQL 18. For PostgreSQL 14–17, install the pg_uuidv7 extension (CREATE EXTENSION pg_uuidv7) which adds the same uuidv7() function. On managed services like Amazon RDS PostgreSQL, check whether the extension is available in the shared preload libraries list.