UUID · Database · PostgreSQL · MySQL · SQLite
UUID as Database Primary Key
Updated: May 2026
Using UUIDs as primary keys is standard practice in distributed applications. The choice of version (v4 or v7) and column type directly impacts index performance and storage size.
Free · No upload · Generated in the browser
PostgreSQL
PostgreSQL has a native UUID type (16 bytes). It is the optimal choice.
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email TEXT NOT NULL
);
For UUID v7 (generated application-side):
CREATE TABLE events (
id UUID PRIMARY KEY, -- generated in app as v7
created_at TIMESTAMPTZ DEFAULT now()
);
MySQL / MariaDB
MySQL has no native UUID type. Two options:
- CHAR(36): human-readable, but 36 bytes vs 16 for BINARY. Slower index.
- BINARY(16): compact, optimal performance. Convert with
UUID_TO_BIN()/BIN_TO_UUID().
CREATE TABLE users (
id BINARY(16) PRIMARY KEY,
email VARCHAR(255)
);
INSERT INTO users (id, email) VALUES
(UUID_TO_BIN(UUID(), 1), 'alice@example.com');
UUID v4 vs v7 for performance
- UUID v4: random insertions in the index → B-tree fragmentation → frequent page rewrites → slower beyond a few million rows.
- UUID v7: sequential insertions at the end of the index → no fragmentation → performance comparable to
BIGINT AUTO_INCREMENT.
For high-volume insert tables (logs, events, audits), prefer UUID v7.
Frequently asked questions
UUID or BIGINT AUTO_INCREMENT?
BIGINT is more compact (8 bytes) and slightly faster. UUID provides universality: client-side generation, database merging, safe API exposure. For distributed or multi-tenant applications, UUID v7 is the standard choice.
Should I index UUID foreign key columns?
Yes, like any foreign key. Without an index, joins on UUID degrade performance quickly.
Do ORMs support UUID v7?
Prisma, Sequelize, TypeORM and Hibernate support application-generated UUIDs. Simply generate a UUID v7 in your code and pass it to the ORM.