UUID vs ULID — Which Should You Use?
Both are 128-bit unique identifiers. ULID is shorter and URL-safe; UUID is a formal RFC standard. Here's how to choose.
What is a ULID?
ULID (Universally Unique Lexicographically Sortable Identifier) is a 128-bit identifier encoding a 48-bit millisecond timestamp and 80 bits of randomness. It looks like this:
01ARZ3NDEKTSV4RRFFQ69G5FAV
That's 26 characters in Crockford Base32 (no hyphens, case-insensitive, no ambiguous characters like I/l or O/0). It was designed as a sortable, URL-safe alternative to UUID.
Side-by-Side Comparison
| Property | UUID (v4) | UUID (v7) | ULID |
|---|---|---|---|
| Bits | 128 | 128 | 128 |
| String length | 36 chars | 36 chars | 26 chars |
| Format | Hex with hyphens | Hex with hyphens | Crockford Base32 |
| URL-safe (no encoding needed) | Yes (hyphens allowed) | Yes | Yes |
| Sortable by creation time | No | Yes | Yes |
| Randomness bits | 122 | 74 | 80 |
| Formal RFC standard | RFC 4122 / RFC 9562 | RFC 9562 | No (community spec) |
| Native database support | PostgreSQL UUID, MySQL 8 | PostgreSQL UUID, MySQL 8 | Needs CHAR(26) or BINARY(16) |
| Standard library support | Python, Java, .NET, Node.js | Python 3.13+, Node uuid 10+ | Third-party packages only |
When to Use ULID
- You're building in a language/framework where ULID has strong library support (JavaScript/TypeScript with
ulidnpm) - The IDs appear in URLs and you want a cleaner, shorter look
- You need sortability and your stack doesn't yet support UUID v7
- You're already using ULID — no reason to migrate
When UUID v7 is Better Than ULID
For most new projects today, UUID v7 is the better choice over ULID because:
- It's an IETF RFC standard (RFC 9562, 2024) — more interoperable
- PostgreSQL, MySQL 8, and SQL Server support UUID columns natively
- UUID v7 has similar database performance benefits to ULID
- No format conversion needed when working with systems that expect UUIDs
Frequently Asked Questions
What is a ULID?
ULID (Universally Unique Lexicographically Sortable Identifier) is a 128-bit identifier that encodes a 48-bit millisecond timestamp and 80 bits of randomness in a 26-character Crockford Base32 string (e.g. 01ARZ3NDEKTSV4RRFFQ69G5FAV). Like UUID v7, it is time-ordered. Unlike UUID, it has no standard hyphens and is case-insensitive.
Is ULID better than UUID?
Neither is universally better. ULID is shorter in string form (26 chars vs 36) and URL-safe without encoding. UUID is a formal RFC standard with universal library support. For new projects that need sortable IDs and don't have legacy UUID constraints, UUID v7 provides the same benefits as ULID with better interoperability.
Can I store a ULID in a UUID database column?
Yes. ULID and UUID v7 both encode 128 bits — a ULID can be stored in a UUID or BINARY(16) column by converting it from Base32 to the standard UUID hex format. Some libraries (e.g. ulid-py) provide this conversion. Alternatively, store ULIDs as CHAR(26) to preserve the Base32 representation.