Menu

PostgreSQL UUID Data Type and UUIDv7

Learn PostgreSQL UUID storage, native UUIDv4 and UUIDv7 generation in PostgreSQL 18, and how to use a UUID as a primary key.

Updated on

A UUID is a 128-bit identifier commonly written as 32 hexadecimal digits in five groups (8-4-4-4-12). PostgreSQL’s uuid data type can store UUIDs from any version.

UUID algorithms make collisions very unlikely, but the data type itself does not enforce uniqueness. Add a PRIMARY KEY or UNIQUE constraint when the value must be unique in a table. UUIDs can also be generated outside one database, which is useful when applications create records across multiple servers.

Generate UUIDs in PostgreSQL

PostgreSQL 18 provides native functions for random UUIDv4 and time-ordered UUIDv7 values:

Function UUID version Behavior
uuidv4() 4 Random UUID.
gen_random_uuid() 4 Random UUID; available as a built-in function in current PostgreSQL releases.
uuidv7() 7 Time-ordered UUID with the generation timestamp encoded in the value.

Generate a random UUIDv4 or a time-ordered UUIDv7:

SELECT uuidv4(), uuidv7();

uuidv4() is available in PostgreSQL 18 and later; gen_random_uuid() is the UUIDv4 function to use on PostgreSQL 13 through 17. PostgreSQL 18 added uuidv7(). The uuid-ossp extension still provides other UUID algorithms, including versions 1, 3, and 5.

PostgreSQL 18 also accepts an optional interval that shifts the timestamp encoded by uuidv7():

SELECT uuidv7(INTERVAL '1 hour');

The shifted timestamp must remain within the range supported by UUIDv7; PostgreSQL raises an error if it falls outside that range. This parameter shifts the UUID’s encoded timestamp and does not set a row’s separate business-event timestamp.

UUIDv7 includes time information, so generated values are generally ordered by generation time and can offer better index locality than random UUIDv4 values. This is workload-dependent: UUIDv7 is not a transaction sequence or a guarantee of exact commit order, and its timestamp can reveal an approximate creation time.

Use UUID as a primary key

Set a default UUID function so callers do not need to supply the primary key:

CREATE TABLE events (
    event_id uuid PRIMARY KEY DEFAULT uuidv7(),
    event_name text NOT NULL,
    created_at timestamptz NOT NULL DEFAULT now()
);

Insert a row and return the generated UUID:

INSERT INTO events (event_name)
VALUES ('account_created')
RETURNING event_id;

If the application needs UUIDv4 instead, use DEFAULT uuidv4() on PostgreSQL 18 or later, or DEFAULT gen_random_uuid() on PostgreSQL 13 and later.

PostgreSQL 18 also provides uuid_extract_version() and uuid_extract_timestamp() to inspect supported UUID values. The timestamp extraction function returns a timestamp for UUID versions 1 and 7; for other versions it returns NULL. An extracted timestamp is not necessarily the exact generation time; that depends on the implementation that created the UUID.

For the storage type details, see the PostgreSQL UUID type reference. For older UUID generation algorithms, see the official uuid-ossp documentation.