Unique identifiers seem like a solved problem until you watch a database slow down under millions of random UUID primary keys. The choice between UUID and ULID is really a choice about whether your IDs carry order — and that has real performance implications.
The UUID (v4) approach
A version-4 UUID is 122 bits of randomness. It is globally unique with negligible collision risk and needs no coordination between systems. That randomness is also its weakness: consecutive inserts land in random positions in a sorted index, causing page splits and poor cache locality in databases that cluster on the primary key.
The ULID approach
A ULID puts a millisecond timestamp in its leading characters, followed by randomness. The result is still effectively unique, but it sorts by creation time. New records append near the end of the index rather than scattering, which keeps inserts fast and indexes compact. ULIDs are also case-insensitive and URL-safe thanks to Crockford base32 encoding.
When to use which
- Use UUID v4 when you need a universal standard, when ordering would leak information you want hidden, or when your storage does not cluster on the key.
- Use ULID when insert performance and natural time-ordering matter, especially for high-volume tables.
Both are easy to generate client-side, so you can adopt either without a central authority issuing IDs.