ULID
ULID (Universally Unique Lexicographically Sortable Identifier) is a 128-bit identifier with millisecond timestamp precision and 80 bits of randomness. ULIDs are URL-safe, use Crockford’s Base32 encoding, and sort lexicographically by creation time.When to Use
Use ULID when you need:- Time-ordered IDs - Sortable by creation time
- URL-safe format - No special characters, case-insensitive
- Compact representation - 26 characters vs UUID’s 36
- Human-readable - Crockford Base32 avoids ambiguous characters (no 0/O or 1/I/l)
ULID is an excellent choice for database primary keys, offering similar benefits to UUID v7 with a more compact string format.
Basic Usage
API Reference
Main Function
Generate a ULID string with current timestamp and automatic monotonic ordering.
Generate a ULID string with custom options.Options:
msecs?: number- Timestamp in milliseconds (defaults toDate.now())random?: Uint8Array- 16 bytes of random data (only first 10 bytes used)
ulid(options, buf, offset)
<TBuf extends Uint8Array>(options: UlidOptions | undefined, buf: TBuf, offset?: number) => TBuf
Write ULID bytes directly into a buffer at the specified offset.Parameters:
options- ULID generation options orundefinedbuf- Target buffer (must have at least 16 bytes available from offset)offset- Starting position in buffer (default: 0)
Static Methods
Convert a ULID string to a 16-byte
Uint8Array.Convert a 16-byte
Uint8Array to a ULID string.Extract the embedded timestamp from a ULID string. Returns milliseconds since Unix epoch.
Validate that a value is a properly formatted ULID string. TypeScript type guard.
Constants
The nil ULID (all zeros):
"00000000000000000000000000"The max ULID (maximum valid value):
"7ZZZZZZZZZZZZZZZZZZZZZZZZZ"Monotonic Ordering
ULID maintains module-level state to ensure IDs generated within the same millisecond remain monotonically increasing:Cloudflare Workers: By default, Cloudflare Workers “freezes” time during request handling to prevent side-channel attacks. This means
Date.now() returns the same value for an entire request, so all ULIDs generated within a single request will have the same timestamp. The monotonic ordering relies entirely on incrementing the random portion.Real-World Examples
Database Primary Keys
File Naming
URL Slugs
Log Correlation
Testing with Deterministic Output
Type Definitions
Structure
ULID consists of 128 bits encoded as 26 Crockford Base32 characters:- First 10 characters: 48-bit timestamp (milliseconds since Unix epoch)
- Last 16 characters: 80 bits of cryptographically secure randomness
Crockford Base32 Alphabet
ULID uses Crockford’s Base32 encoding, which excludes ambiguous characters:I, L, O, U (easily confused with 1, 0, etc.)
Performance Characteristics
Generation Speed
85× faster than
ulid npm packageSortability
Lexicographically sortable by creation time
Compactness
26 characters (28% shorter than UUID)
Entropy
80 bits of cryptographically secure randomness
Bundle Size: ~1.5 KB minified + gzipped
Validation Pattern
ULID must match this pattern:- Exactly 26 characters
- First character is
0-7(prevents timestamp overflow) - Remaining characters from Crockford Base32 alphabet
- Case-insensitive
