UUID v4 — pure randomness
UUID v4 is the format most developers know: 128 bits of randomness rendered as 32 hex characters with dashes ('550e8400-e29b-41d4-a716-446655440000'). It is the safest default for systems that mix data from many sources without coordination, since collisions are astronomically unlikely. The downside is index fragmentation: every new row lands in a random spot in B-tree indexes, hurting write throughput and cache locality.
UUID v7 — time-ordered random
UUID v7 (standardized in RFC 9562) keeps the UUID format but encodes a millisecond Unix timestamp into the leading 48 bits, followed by randomness. The result is a UUID that sorts chronologically while keeping enough randomness to prevent collisions. New rows now land at the end of the index, restoring write performance. Most major languages have UUID v7 libraries as of 2024–2025.
ULID — UUID's cousin, sortable by design
ULID (Universally Unique Lexicographically Sortable Identifier) is a different specification that predates UUID v7 by several years. It uses 128 bits like UUIDs but encodes them in 26-character Crockford Base32 ('01ARZ3NDEKTSV4RRFFQ69G5FAV') for shorter, URL-friendly text. The first 48 bits are a Unix millisecond timestamp, the rest is random. Functionally very similar to UUID v7 but with a different text form.
Index performance
B-tree indexes prefer monotonic inserts. UUID v4 inserts hot random pages all over the index, causing page splits and high IO. UUID v7 and ULID insert at the end almost exclusively, which is dramatically friendlier to the storage layer — typically 2–5x faster bulk inserts on tables with hundreds of millions of rows.
Privacy and information leakage
Sortable IDs leak creation order publicly. If user IDs are sequential or timestamp-based, anyone can enumerate your user count or infer onboarding patterns. UUID v7 and ULID expose the millisecond an entity was created. If that's sensitive (medical records, internal IDs visible to users), use UUID v4 or hash the displayed ID.
Format details
- UUID v4: 36 chars including dashes, 128 bits random.
- UUID v7: 36 chars including dashes, 48-bit timestamp + 74 bits random + version/variant bits.
- ULID: 26 chars no dashes, 48-bit timestamp + 80 bits random, Crockford Base32 alphabet (no I/L/O/U).
Migration considerations
If you are currently using UUID v4 and want sortable IDs, you can usually migrate by writing new rows as UUID v7 / ULID while keeping old rows as v4. The format is the same length, so the column doesn't need to change. The migration is invisible to application code — you just need to swap the ID generation library.