UUID vs. ULID: Choosing the Right Unique Identifier
When building applications that need unique identifiers for records, two popular formats stand out: UUID (Universally Unique Identifier) and ULID (Universally Unique Lexicographically Sortable Identifier). Understanding their differences helps you choose the right one for your use case.
What Is a UUID?
UUID is defined by RFC 4122. The most common variant, UUID v4, is 128 bits of essentially random data:
550e8400-e29b-41d4-a716-446655440000
Format: 8-4-4-4-12 hexadecimal characters separated by hyphens (36 chars total).
UUID Versions
- v1: Timestamp + MAC address. Sortable but exposes hardware info
- v4: Random. Most widely used — no information exposed
- v5: Namespace + SHA-1 hash. Deterministic from input
- v7 (2023): Unix timestamp + random. Sortable — the modern recommendation
- v8: Custom/application-defined layout
What Is a ULID?
ULID is a 128-bit identifier designed to be both unique and naturally sortable:
01ARZ3NDEKTSV4RRFFQ69G5FAV
Structure: 26 characters using Crockford's Base32 (0-9 and A-Z excluding I, L, O, U for readability)
- First 10 characters: 48-bit Unix millisecond timestamp
- Last 16 characters: 80 bits of randomness
Key Differences
| Property | UUID v4 | UUID v7 | ULID |
|---|---|---|---|
| Length | 36 chars (with hyphens) | 36 chars | 26 chars |
| Sortable | No | Yes (by creation time) | Yes (by creation time) |
| Timestamp-based | No | Yes (ms precision) | Yes (ms precision) |
| Case-sensitive | No | No | No |
| URL-safe | No (hyphens) | No (hyphens) | Yes |
| Monotonic within ms | No | Optional | Yes (each ULID increments) |
| Bit size | 128 bits | 128 bits | 128 bits |
Database Performance Implications
The UUID v4 Index Problem
Random UUIDs cause poor database performance when used as primary keys because:
- New records insert randomly throughout the B-tree index
- Causes page splits and fragmentation
- Reduces cache effectiveness (each insert touches a different page)
Sequential IDs Are Faster
ULIDs and UUID v7 insert in time order, meaning:
- New records are typically appended to the end of the index
- Better cache utilization (recent data is "hot")
- Fewer page splits
- Better range scan performance for time-based queries
For high-write workloads, the difference can be 2-10x in insertion performance.
When to Use UUID v4
- When you need compatibility with existing systems using UUID v4
- When you must not leak timestamp information in the ID
- When random distribution is specifically desired
- For identifiers not used as database primary keys (session tokens, etc.)
When to Use ULID or UUID v7
- As database primary keys in append-heavy tables
- When IDs should be roughly time-sortable
- When you want URL-safe IDs (ULID has no hyphens)
- For distributed systems where IDs are generated across multiple nodes
Security Considerations
- UUID v4 and ULID are NOT cryptographically secure — don't use them as secret tokens or authentication keys
- UUID v1's MAC address embedding exposes hardware information (privacy concern)
- ULIDs/UUID v7 timestamp exposure: anyone with the ID can determine approximately when a record was created
For secret tokens (password reset, API keys, session IDs), use cryptographically secure random generators.
Using the UUID and ULID Generators
Our tool provides:
- Generate UUIDs — versions 1, 4, 5, and 7 supported
- Generate ULIDs — time-sorted, URL-safe identifiers
- Bulk generation — create multiple IDs at once
- Timestamp extraction — for ULID and UUID v7, shows the encoded timestamp
- Copy to clipboard — single or all generated IDs
Use it for testing, seeding databases, generating unique identifiers for mock data, and understanding the structure of different ID formats.