UUID vs ULID
Compare UUID and ULID by format, length, time ordering, randomness, database usage, performance and practical use cases.
UUID and ULID are both identifiers designed to make it possible to create unique values across distributed applications without relying on a central counter. They solve many of the same problems, but they use different formats and provide different characteristics. UUID is a long-established standardized identifier family with multiple versions, while ULID is designed around compact, lexicographically sortable identifiers that combine a timestamp with randomness.
The choice between UUID and ULID often comes down to a few practical questions: Do identifiers need to sort by creation time? Does the database provide native UUID support? Is a fixed textual format important? Should the timestamp be visible? Is compatibility with existing systems required? Understanding these differences helps avoid choosing an identifier format based only on appearance.
UUID vs ULID at a Glance
| Property | UUID | ULID |
|---|---|---|
| Typical text length | 36 characters | 26 characters |
| Binary size | 128 bits | 128 bits |
| Alphabet | Hexadecimal | Crockford Base32 |
| Timestamp | Depends on UUID version | Yes |
| Lexicographically sortable | Depends on version | Yes |
| Standardized | Yes | Defined specification |
| Common random version | UUID v4 | ULID |
| Time-ordered alternative | UUID v7 | Native characteristic |
What Is a UUID?
UUID stands for Universally Unique Identifier. A UUID is a 128-bit identifier normally represented as 32 hexadecimal characters separated by hyphens.
550e8400-e29b-41d4-a716-446655440000UUID is actually a family of identifier formats rather than a single generation algorithm. UUID versions include v1, v3, v4, v5 and v7. Different versions provide different properties: some are time-based, some deterministic, some random and UUID v7 combines timestamp information with randomness.
What Is a ULID?
ULID stands for Universally Unique Lexicographically Sortable Identifier. It is a 128-bit identifier represented as a 26-character string. A ULID combines a 48-bit millisecond timestamp with 80 bits of randomness.
01ARZ3NDEKTSV4RRFFQ69G5FAVThe timestamp occupies the first 10 characters of the textual representation, while the remaining 16 characters encode the random component. Because the timestamp comes first, ULIDs generated at different times naturally have chronological lexicographic ordering.
| ULID Component | Size |
|---|---|
| Timestamp | 48 bits |
| Randomness | 80 bits |
| Total | 128 bits |
| Text representation | 26 characters |
The Biggest Difference: Sortability
One of the defining characteristics of ULID is that its textual representation is lexicographically sortable by creation time. When ULIDs are generated at different timestamps, sorting their strings generally places earlier identifiers before later identifiers.
01ARZ3NDEKTSV4RRFFQ69G5FAV
01ARZ3NDF6TQ9Y8K4M3P2J7C1B
01ARZ3NDG2J8QW6N5R4S3T2U1VThis property can be useful for database indexes, logs, event streams and systems where records are frequently retrieved in creation order.
Are All UUIDs Sortable by Time?
No. UUID sortability depends on the UUID version and representation. UUID v4 is generated randomly, so its values do not naturally sort according to creation time. UUID v1 contains timestamp information, but its textual ordering characteristics are different from the straightforward chronological ordering provided by ULID.
UUID v7 is the important modern comparison. Like ULID, UUID v7 places timestamp information at the beginning of the identifier and is designed to provide useful time ordering. This means the practical choice is not always simply UUID versus ULID; it can also be UUID v7 versus ULID.
UUID v7 vs ULID
UUID v7 and ULID are conceptually similar because both combine time information with randomness and are designed to provide identifiers that work well in systems where chronological ordering matters.
| Feature | UUID v7 | ULID |
|---|---|---|
| Total size | 128 bits | 128 bits |
| Timestamp | Unix timestamp | Unix timestamp in milliseconds |
| Random component | Large random component | 80 bits |
| Text length | 36 characters | 26 characters |
| Alphabet | Hexadecimal | Crockford Base32 |
| Hyphens | Yes | No |
| UUID ecosystem compatibility | Yes | No |
| Lexicographic ordering | Designed for time ordering | Yes |
ULID has a more compact textual representation, while UUID v7 has the advantage of belonging to the standardized UUID family. For a new system, both can be reasonable choices when time ordering is desirable.
Why Is ULID Only 26 Characters?
ULID uses Crockford Base32 instead of hexadecimal. A Base32 alphabet can encode more information per character than hexadecimal, so fewer characters are required to represent the same 128-bit value.
| Format | Alphabet Size | Typical Length |
|---|---|---|
| UUID text | 16 hexadecimal symbols | 36 characters |
| ULID | 32 Base32 symbols | 26 characters |
The UUID's 36-character representation also includes four hyphens. ULID uses a continuous 26-character string, which can make it more convenient for URLs, database keys, logs and other text-heavy environments.
Crockford Base32
ULID uses Crockford Base32, an alphabet designed to be relatively easy for humans to read and transcribe. It avoids some characters that can be confused visually, such as I, L and O.
0123456789ABCDEFGHJKMNPQRSTVWXYZThe alphabet is case-insensitive in the intended textual representation, which can make ULIDs convenient when identifiers may be copied or entered manually. Applications should nevertheless define a consistent canonical representation when identifiers are stored or exchanged.
UUID and ULID Both Have 128 Bits
Although ULID is shorter as a string, it is not smaller as an identifier. Both UUID and ULID represent 128 bits of information. The difference is how those bits are organized and encoded for human-readable text.
UUID: 128 bits → hexadecimal text → 36 characters
ULID: 128 bits → Base32 text → 26 charactersThis distinction is important because a shorter textual representation does not automatically mean less storage at the binary level. Storage requirements depend on how the application or database stores the identifier.
How ULID Timestamps Work
A ULID contains a 48-bit timestamp representing milliseconds since the Unix epoch. This timestamp occupies the most significant part of the identifier.
48-bit timestamp + 80-bit randomness = 128 bitsBecause the timestamp appears first, two ULIDs generated at different times will normally sort in chronological order when compared as strings. This is one of the main reasons developers choose ULID instead of a completely random identifier.
Does ULID Reveal Creation Time?
Yes. A ULID contains a timestamp, so someone who can decode the identifier can determine its encoded creation time to millisecond precision within the timestamp range. This can be useful for debugging and ordering but can also reveal metadata that a random UUID v4 would not intentionally expose.
UUID v4 and ULID
UUID v4 and ULID are often compared because both can provide randomly generated identifiers. Their major difference is that ULID dedicates part of its 128 bits to a timestamp, while UUID v4 uses its available identifier space primarily for randomness.
| Feature | UUID v4 | ULID |
|---|---|---|
| Total bits | 128 | 128 |
| Random bits | 122 | 80 |
| Timestamp | No | 48 bits |
| Text length | 36 | 26 |
| Chronological sorting | No | Yes |
| Standard UUID format | Yes | No |
This means ULID trades some random space for timestamp information. The remaining 80 random bits still provide an enormous number of possible values within a timestamp, making accidental collisions extremely unlikely for normal workloads.
Collision Resistance
Neither UUID nor ULID provides an absolute mathematical guarantee that two generated identifiers can never be identical. They provide identifier spaces large enough that accidental collisions are extremely unlikely when implementations follow their intended generation rules.
For ULID, the random component contains 80 bits. For UUID v4, 122 bits are available for random data after the bits reserved for version and variant information. UUID v7 also allocates a large portion of its value to randomness after accounting for its timestamp and required fields.
ULID Monotonic Generation
A useful ULID feature is monotonic generation. If multiple ULIDs are generated during the same millisecond, an implementation can increment the random component rather than generating unrelated random values for every identifier. This can preserve ordering among identifiers produced within the same timestamp.
This behavior is implementation-dependent and should not be confused with a global sequence number. Multiple processes or machines can still generate identifiers independently, and applications should not assume that ULIDs provide a centralized total ordering across an entire distributed system.
UUID vs ULID for Databases
Database behavior is one of the most important considerations when choosing between UUID and ULID. Random identifiers can lead to insertion patterns that are less sequential than traditional integer keys. Time-ordered identifiers can provide better locality in some workloads because newly created records tend to be near other recently created records in the index.
ULID and UUID v7 are both designed to provide useful temporal ordering. This can make them attractive alternatives to random UUID v4 for workloads with heavy insert activity.
| Identifier | Ordering | Typical Database Consideration |
|---|---|---|
| UUID v4 | Random | Can produce less sequential index access |
| UUID v7 | Time ordered | Better temporal locality |
| ULID | Lexicographically time ordered | Useful for chronological indexes |
Actual performance depends on the database engine, index structure, storage representation, page size, workload and query patterns. A time-ordered identifier is not a universal performance guarantee.
ULID as a Database Primary Key
ULIDs can be used as primary keys when the database stores them efficiently and the application benefits from their ordering properties. Their 26-character textual form is convenient, but storing identifiers as text can use more space than a compact binary representation.
If a database has a native UUID type, UUID can have an advantage because the database already understands the identifier's binary representation and provides established indexing behavior. With ULID, applications may need to choose between text storage and a custom binary representation.
UUID vs ULID Storage
| Storage Approach | UUID | ULID |
|---|---|---|
| Native UUID type | Widely supported | Usually not native |
| Text storage | Common | Common |
| Binary storage | 128 bits | 128 bits |
| Canonical text length | 36 | 26 |
| Database ecosystem | Very mature | Depends on database |
When evaluating storage, it is important to distinguish the textual representation from the underlying identifier. A 26-character ULID string is shorter than a 36-character UUID string, but both can represent 128-bit values. A database storing both as binary values can therefore use the same amount of raw identifier storage before accounting for indexes and other database structures.
UUID vs ULID for URLs
ULID has an advantage in URLs because its canonical representation is only 26 characters and contains no hyphens. A UUID string is longer and includes punctuation.
UUID:
https://example.com/orders/550e8400-e29b-41d4-a716-446655440000
ULID:
https://example.com/orders/01ARZ3NDEKTSV4RRFFQ69G5FAVThe difference is not enormous for a single URL, but it can become significant in systems that expose identifiers in millions of links, logs, API responses or cached resources.
UUID vs ULID for APIs
Both UUID and ULID work well as API resource identifiers. UUID has the advantage when the API must follow an established standard or integrate with third-party systems that expect UUID syntax. ULID is attractive when an API wants compact identifiers and clients can treat them as opaque strings.
An API should document its identifier format clearly. Clients should not assume that every identifier is a UUID merely because it looks like a random string.
UUID vs ULID Security
Neither UUID nor ULID should be considered an authorization mechanism. A sufficiently random identifier can make resource enumeration difficult, but access control must still be enforced by the application.
ULID has an additional consideration because its timestamp is visible. UUID v4 does not intentionally encode creation time, making it preferable when identifiers should not reveal this particular piece of metadata.
UUID vs ULID Performance
Identifier generation itself is usually a very small part of an application's total workload. Database access, network requests, serialization and business logic generally have a much larger impact on application performance.
The more meaningful performance difference can appear in database indexing. Random UUID v4 values do not naturally progress through an index, while ULID and UUID v7 provide time-related ordering that can be beneficial for insertion-heavy workloads.
UUID vs ULID: Human Readability
Neither identifier is intended to be human-readable in the sense of conveying meaningful words or names. However, ULID's Crockford Base32 representation can be easier to copy or inspect manually because it avoids hyphens and uses an alphabet designed to reduce visual ambiguity.
UUID's hexadecimal format is more familiar to developers and is widely recognized by tools and debugging environments. Which format is easier to work with therefore depends partly on the context.
UUID Ecosystem and Interoperability
UUID has a major ecosystem advantage. UUID support is built into many programming languages, databases, frameworks, validation libraries, API schemas and development tools. Organizations often already have conventions for UUID-based identifiers.
ULID has strong library support as well, but it does not have the same decades-long ecosystem footprint as UUID. If an existing system already expects UUID values, introducing ULID may require additional validation, storage and integration work.
When to Choose UUID
- The application needs a widely recognized standard.
- Multiple services need to exchange identifiers.
- The database has native UUID support.
- Third-party APIs require UUID values.
- The application already uses UUIDs extensively.
- A standardized UUID v7 time-ordered identifier is sufficient.
- Maximum ecosystem compatibility is more important than a shorter string.
When to Choose ULID
- Lexicographical time ordering is useful.
- Compact identifiers are desirable.
- Identifiers frequently appear in URLs.
- A 26-character canonical representation is convenient.
- The application wants timestamp information embedded in the identifier.
- The system does not need UUID-specific interoperability.
- Database or application workflows benefit from time-oriented identifiers.
When UUID v4 Is Better Than ULID
UUID v4 is often preferable when identifiers should be random and should not intentionally reveal creation time. It is also a strong choice when compatibility with existing UUID infrastructure matters.
For example, an application creating identifiers for objects that may be synchronized between independent services can benefit from the standardized UUID format and broad library support.
When UUID v7 Is Better Than ULID
UUID v7 is an especially important alternative to ULID for new applications. Both provide timestamp-based ordering, but UUID v7 is part of the UUID family and therefore fits naturally into systems that already use UUID types, validation and tooling.
If an application wants time-ordered identifiers without abandoning its existing UUID-based architecture, UUID v7 can be a natural choice.
ULID vs UUID: A Practical Decision
| Requirement | Recommended Choice |
|---|---|
| Maximum UUID ecosystem compatibility | UUID |
| Simple random identifier | UUID v4 |
| Time-ordered standardized UUID | UUID v7 |
| Compact time-ordered identifier | ULID |
| Short URL identifier | ULID |
| Native database UUID support | UUID |
| Visible creation timestamp | ULID or UUID v7 |
| Avoid exposing timestamp | UUID v4 |
Common UUID vs ULID Mistakes
- Assuming every UUID is random.
- Assuming every UUID sorts chronologically.
- Assuming ULID and UUID have different binary sizes.
- Ignoring the timestamp information encoded in ULIDs.
- Choosing ULID without checking database storage options.
- Choosing UUID v4 when chronological ordering is important.
- Assuming time ordering guarantees global ordering in a distributed system.
- Using either identifier as a replacement for authorization.
- Ignoring compatibility requirements with existing APIs and databases.
Best Practices
- Choose identifiers according to application requirements rather than popularity.
- Use UUID v4 when a standardized random identifier is sufficient.
- Consider UUID v7 when time ordering and UUID compatibility are both important.
- Consider ULID when compact, lexicographically sortable identifiers are valuable.
- Remember that ULIDs contain timestamp information.
- Use secure randomness for the random portion of generated identifiers.
- Consider database-native UUID support before adopting ULID.
- Measure actual database performance instead of assuming one identifier is always faster.
- Keep authorization separate from identifier generation.
- Document identifier formats in public APIs and database schemas.
Frequently Asked Questions
Is ULID better than UUID?
Neither is universally better. ULID is shorter and naturally lexicographically sortable by time, while UUID has broader standardization, native database support and ecosystem compatibility.
Is ULID a UUID?
No. ULID and UUID are different identifier formats. Both are 128 bits, but they encode and represent those bits differently.
Why is ULID shorter than UUID?
ULID uses a Base32 representation and does not include UUID-style hyphens. Its 128-bit value is represented using 26 characters instead of the conventional 36-character UUID string.
Does ULID contain a timestamp?
Yes. ULID contains a 48-bit timestamp representing milliseconds since the Unix epoch. This timestamp forms the most significant part of the identifier.
Can ULIDs be sorted?
Yes. ULIDs are designed so their canonical string representation sorts lexicographically according to the timestamp component. This makes them useful when chronological ordering is desirable.
Is UUID v7 better than ULID?
It depends on the application. UUID v7 provides similar time-ordering characteristics while remaining part of the UUID ecosystem. ULID is shorter as a string and uses a compact Base32 representation.
Is ULID secure?
ULID can provide strong random identifiers when generated with a suitable secure random source, but the identifier itself should not be treated as an authorization mechanism. ULIDs also reveal their timestamp component.
Can ULID be used as a database primary key?
Yes. ULID can work well as a primary key, particularly when time ordering is useful. However, the database's storage and indexing capabilities should be considered because ULID does not have the same native support as UUID in many systems.
Should I use UUID v4, UUID v7 or ULID?
Use UUID v4 for a standardized random identifier, UUID v7 for a standardized time-ordered UUID, and ULID when compact lexicographically sortable identifiers are especially valuable.
Helpful Identifier Tools
A UUID Generator creates standard UUID values, a ULID Generator creates time-ordered ULIDs, a UUID Validator checks whether a UUID has a valid structure, a UUID Version Detector identifies the UUID version, and a Secure Random Generator can generate cryptographically secure random values for applications that require them.
Conclusion
UUID and ULID are both 128-bit identifier formats, but they make different trade-offs. UUID has a mature standardized ecosystem, multiple versions and broad database support. ULID focuses on compact representation, timestamp-based ordering and a URL-friendly 26-character format.
For a simple standardized random identifier, UUID v4 remains a strong choice. For time-ordered identifiers within the UUID ecosystem, UUID v7 is an excellent option. For compact identifiers that naturally sort by time and do not need UUID-specific compatibility, ULID can be a strong alternative.
The right choice ultimately depends on the surrounding system. Consider database support, API compatibility, identifier length, ordering requirements, timestamp visibility, randomness and security before deciding between UUID and ULID.