ULID (Universally Unique Lexicographically Sortable Identifier) and UUID (Universally Unique Identifier) are two of the most widely discussed approaches to generating unique identifiers in modern software systems. UUID v4, defined by RFC 4122, has been the industry default for decades and relies on 122 bits of cryptographic randomness to produce identifiers that are virtually guaranteed to be unique. ULID, introduced as an alternative in 2016, embeds a 48-bit millisecond-precision timestamp in the first portion of the identifier, making the resulting values lexicographically sortable by creation time while still providing 80 bits of randomness for uniqueness.
One of the most significant practical differences between the two formats lies in how they interact with database indexes. Because UUID v4 values are entirely random, inserting them into a B-tree index causes random page splits and write amplification, which degrades performance at scale. ULID values, by contrast, are roughly monotonically increasing over time, so new entries are appended near the end of the index, producing far less fragmentation and significantly better write throughput. This makes ULID an especially attractive option for high-write workloads or event-sourcing architectures where ordering matters.
From an encoding perspective, ULID uses Crockford's Base32 to produce a compact 26-character string that is URL-safe, case-insensitive, and free of ambiguous characters. UUID v4, on the other hand, uses the familiar 8-4-4-4-12 hexadecimal format, resulting in a 36-character string (or 32 characters without hyphens). While UUID enjoys universal recognition and native support in virtually every programming language and database, ULID offers a leaner representation and built-in time information without sacrificing uniqueness guarantees in the vast majority of real-world scenarios.
| Property | ulid | uuid |
|---|---|---|
| Bit Length | 128 | 128 |
| Output Length | 26 | 36 |
| Encoding | Crockford base32 | hex (8-4-4-4-12) |
| Sortable | Yes | No |
| Timestamped | Yes | No |
| Monotonic | Yes | No |
| Crypto Random | Yes | Yes |
| Standard | — | RFC 4122 |
Choose UUID v4 when broad ecosystem compatibility, standards compliance, and native database support are your top priorities. Choose ULID when you need time-sortable identifiers, compact encoding, or better database write performance. If you want the best of both worlds, UUID v7 (RFC 9562) combines a time-ordered layout with the standard UUID format, making it a strong middle-ground option for new projects.
Yes. Both ULID and UUID v4 are 128-bit values, so you can convert between them at the binary level. Many ULID libraries provide a toUUID() method that reformats the 128 bits into the standard 8-4-4-4-12 hex representation, and the reverse conversion is equally straightforward.
No. ULID provides 80 bits of randomness per millisecond, while UUID v4 provides 122 bits of randomness overall. In practice, both offer collision probabilities that are astronomically small for any realistic workload, but UUID v4 has a mathematically larger random space.
In most cases, migrating existing data is unnecessary and risky. If your system works well with UUID v4, keep it. Consider adopting ULID (or UUID v7) for new tables or services where sortability and write performance are measurably important, and let the two formats coexist.
© 2024 Carova Labs. All rights reserved