UUID vs ULID: Which Should You Use?
Both UUIDs and ULIDs solve the problem of generating globally unique identifiers without a central authority. But they take different approaches to format, sortability, and developer experience. Here is how to choose between them.
Quick Comparison
| Feature | UUID v4 | UUID v7 | ULID |
|---|---|---|---|
| Size | 128 bits / 16 bytes | 128 bits / 16 bytes | 128 bits / 16 bytes |
| Text length | 36 chars (with hyphens) | 36 chars (with hyphens) | 26 chars |
| Sortable | No (random) | Yes (time-ordered) | Yes (time-ordered) |
| Characters | 0-9, a-f (hex) | 0-9, a-f (hex) | Crockford Base32 |
| URL-safe | Yes | Yes | Yes |
| Standard | RFC 4122 | RFC 9562 (draft) | Unofficial spec |
What is ULID?
ULID (Universally Unique Lexicographically Sortable Identifier) encodes 128 bits into 26 characters using Crockford Base32. The format is: a 48-bit timestamp (in milliseconds) + 80 bits of randomness. Example:
01ARZ3NDEKTSV4RRFFQ69G5FAV ULIDs can be sorted lexicographically (as strings) and the resulting order matches chronological order. This makes them more B-tree-friendly than random UUID v4.
Database Performance
Random UUID v4 inserts typically cause page splits in B-tree indexes because new values can land anywhere in the index. ULID and UUID v7 avoid this by generating time-ordered values that naturally append to the end of the index.
| Identifier | B-tree Performance |
|---|---|
| Auto-increment integer | Excellent |
| UUID v7 | Good (time-ordered) |
| ULID | Good (time-ordered) |
| UUID v4 | Poor (random, causes page splits) |
When to Choose ULID
- You need compact, human-readable IDs — 26 chars vs 36 for UUID
- You want string-sortable IDs — ULIDs sort chronologically as strings
- You prefer all-uppercase strings with no special characters
- You are on a newer codebase where library availability is not a legacy concern
When to Choose UUID
- You need an official standard — UUID is defined by RFC 4122 / 9562
- You need wide ecosystem support — every database, language, and framework understands UUIDs
- Your database has native UUID type — PostgreSQL, MySQL 8.0+, SQL Server all support UUID natively
- You can use UUID v7 — it gives you time-ordered IDs with the UUID standard
- You use Notion or other tools that rely on UUIDs
The Bottom Line
For most new projects, UUID v7 is the best of both worlds. It retains the UUID format your database and tools already understand, while providing chronological sortability like ULID. If your database or ORM does not yet support UUID v7 natively, ULID is a strong alternative.