How to Generate a UUID in PostgreSQL
The simplest way to generate a UUID in PostgreSQL (13 and later) is the built-in gen_random_uuid() function — no extensions, no setup. The rust uuid guide covers the uuid crate with feature flags for v4, v7, serde, and async runtime support.
-- PostgreSQL 13+: gen_random_uuid() is built in, no extension needed
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) NOT NULL
);
-- Generate one directly in a query
SELECT gen_random_uuid();
-- Output: 550e8400-e29b-41d4-a716-446655440000
Explanation
gen_random_uuid()has been part of PostgreSQL core since version 13 — noCREATE EXTENSIONstatement required.- Setting it as a column
DEFAULTmeans everyINSERTwithout an explicitidgets a fresh UUID automatically. - The
UUIDcolumn type stores the value as 16 raw bytes internally, not as a 36-character string, so it uses less space and compares faster thanVARCHAR(36). - Call
gen_random_uuid()directly in aSELECTwhen you just need a one-off identifier without a table.
Convert a String to a UUID in PostgreSQL
A UUID sent as a string — from an API request or an application layer — needs to be cast to PostgreSQL's native UUID type before it can be compared or stored efficiently. Try the uuid v4 generator for UUID v4 generation — the simplest, most private format for general-purpose identifiers.
-- Cast a string literal to the UUID type
SELECT '550e8400-e29b-41d4-a716-446655440000'::uuid;
-- Or using CAST()
SELECT CAST('550e8400-e29b-41d4-a716-446655440000' AS uuid);
-- Comparing a string against a UUID column works via implicit cast
SELECT * FROM users WHERE id = '550e8400-e29b-41d4-a716-446655440000';
Explanation
- The
::uuidcast operator validates the string's format and raises an error immediately if it isn't a well-formed UUID. - PostgreSQL accepts UUID strings with or without hyphens, as long as they contain 32 hex characters.
- Comparing a
VARCHARstring directly against aUUIDcolumn triggers an implicit cast, so explicit casting isn't strictly required inWHEREclauses — but it documents intent clearly. - Casting an invalid string raises
ERROR: invalid input syntax for type uuid— catch this in application code to return a clean error instead of a raw database exception.
Other Options for Generating UUIDs in PostgreSQL
PostgreSQL doesn't have native UUID v7 support yet, and versions before 13 need the uuid-ossp extension for any built-in generation function at all. The mongodb uuid reference explains UUID subtype 3 vs subtype 4 and their impact on query performance.
-- PostgreSQL < 13: enable the uuid-ossp extension once per database
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- Version 4 (random) via uuid-ossp
SELECT uuid_generate_v4();
-- Version 1 (timestamp + MAC address) via uuid-ossp
SELECT uuid_generate_v1();
-- UUID v7 (time-sortable) isn't built in yet -- generate it in application
-- code (see the python uuid / rust uuid guides) and insert it as a plain UUID.
Explanation
uuid-osspis a bundled PostgreSQL extension, not a third-party install —CREATE EXTENSION IF NOT EXISTS "uuid-ossp"enables it once per database, including on managed hosts like RDS or Supabase.uuid_generate_v4()behaves identically to the built-ingen_random_uuid()— prefer the built-in on PostgreSQL 13+ to avoid the extension dependency.uuid_generate_v1()embeds a timestamp and MAC address, making rows sortable by creation time but leaking hardware information — avoid it for public-facing identifiers.- Since PostgreSQL has no native v7 generator, time-sortable UUIDs are typically generated in application code and inserted as a plain UUID value.