What is ULID?
ULID (Universally Unique Lexicographically Sortable Identifier) is a 128-bit identifier format designed to overcome limitations in UUIDs. It consists of:
- Timestamp: 48 bits of millisecond precision Unix time
- Randomness: 80 bits of cryptographically-secure random data
- Encoding: Base32 representation (26 characters)
Format example: 01ARZ3NDEKTSV4RRFFQ69G5FAV
How ULID works
- Generate 48 bits for timestamp (Unix time in milliseconds)
- Generate 80 bits of cryptographically-secure random data
- Combine timestamp (most significant) with randomness (least significant)
- Encode the entire 128-bit value using Crockford's Base32 alphabet
- Result is a 26-character string (first 10 chars are timestamp, last 16 are randomness)
Advantages & Considerations
Advantages | Considerations |
---|---|
|
|
ULID Structure
Component | Bits | Characters | Description |
---|---|---|---|
Timestamp | 48 bits | 10 chars | Unix timestamp (ms) encoded in Base32 |
Randomness | 80 bits | 16 chars | Random bytes encoded in Base32 |
ULID vs. UUID Comparison
Feature | ULID | UUID v1 | UUID v4 | UUID v7 |
---|---|---|---|---|
Size | 128 bits | 128 bits | 128 bits | 128 bits |
String length | 26 chars | 36 chars | 36 chars | 36 chars |
Time-based | ✅ | ✅ | ❌ | ✅ |
Natural sorting | ✅ | ❌ | ❌ | ✅ |
URL safe | ✅ | ❌ | ❌ | ❌ |
MAC address exposure | ❌ | ✅ | ❌ | ❌ |
Random component | ✅ | ❌ | ✅ | ✅ |
Canonical standard | ❌ | ✅ | ✅ | ⚠️ Draft |
Common Use Cases
- Database primary keys: Performance-optimized indexes
- Distributed systems: Coordination-free generation
- APIs: Clean, URL-safe identifiers
- Time-series data: Native chronological ordering
- Log systems: Sortable event identifiers
- Modern applications: Where UUID limitations are problematic
Why Choose ULID?
- Sortability: Lexicographically sorts by creation time
- URL safety: No URL encoding needed (unlike UUIDs with hyphens)
- Compactness: 26 characters vs 36 for UUID
- Case insensitivity: Reduces user input errors
- Monotonicity: Optional monotonic sorting within same millisecond
- No special characters: Simple, alphanumeric-only format
Frequently Asked Questions
How does ULID compare to UUID v7?
Both use Unix timestamps for sortability and have random components. The key differences are encoding (Base32 vs hex), format (26 characters vs 36), and standardization (UUID v7 is in draft RFC specification).
Can I extract the creation time from a ULID?
Yes. The first 10 characters represent a millisecond-precision Unix timestamp that can be decoded and converted to a standard datetime.
Are ULIDs compatible with UUID database fields?
No. ULIDs use a different format and would need to be stored as strings or binary data rather than in native UUID database types.
What is monotonicity in ULIDs?
Some ULID implementations offer a monotonic option that ensures sequential sort order even within the same millisecond by incrementing the random component for ULIDs created in the same timestamp.
What character set does ULID use?
ULID uses Crockford's Base32 encoding (0-9, A-Z excluding I, L, O, U) which is designed to minimize confusion and transcription errors when IDs are read or entered manually.
Resources
Crockford's Base32 Alphabet
Encoding Value | Character | Notes |
---|---|---|
0-9 | 0-9 | Decimal digits |
10-31 | A-Z | Excluding I, L, O, U for readability |
Characters: 0123456789ABCDEFGHJKMNPQRSTVWXYZ
This encoding is case-insensitive for decoding (but ULIDs are typically generated in uppercase).