Sequential integer IDs are simple and fast β until you add a second database node, a microservice that generates its own records, or a client that needs to create IDs before the server confirms them. UUID solves the coordination problem integers cannot.
When to Use UUID Primary Keys
Use UUIDs when: multiple services or database nodes generate records independently without coordination. Client-side ID generation is needed (mobile apps, offline-first systems). Records are merged from multiple databases and integer ID conflicts would occur. You want to avoid exposing sequential record counts to users.
UUID Version Comparison
UUID v4 β Pure random, 122 bits of entropy. Ideal for security-sensitive identifiers. Causes B-tree index fragmentation due to random insertion order. UUID v7 β Time-ordered with millisecond precision prefix. Sorts chronologically, dramatically reducing index fragmentation. The recommended choice for new database primary keys in 2025.
Generate UUID v4 identifiers in bulk β up to 100 at once β with the UUID Generator. One-click copy all for seeding databases and test fixtures.
PostgreSQL Implementation
Use the uuid-ossp extension: CREATE EXTENSION IF NOT EXISTS uuid-ossp. Primary key: id UUID DEFAULT uuid_generate_v4() PRIMARY KEY. For UUID v7 in PostgreSQL 17+, use the built-in gen_random_uuid() which now produces time-ordered UUIDs.
The Index Performance Reality
At small scales (under 10 million rows), UUID v4 vs integer performance is negligible. At large scales, UUID v4 fragmentation can increase index size by 30-50% and slow inserts measurably. UUID v7 eliminates most of this fragmentation. If you cannot use v7, consider ULID as an alternative time-ordered unique identifier.