ULID Generator

Crockford Base32 Sortable

Generate 128-bit Universally Unique Lexicographically Sortable Identifiers. 26-character Crockford's Base32 format, URL-safe, millisecond timestamp precision, and zero hyphens.

Generating...
Max 1,000
Keyboard shortcuts: Press R or Space to regenerate ยท C to copy
Format: Crockford's Base32 Precision: 1ms Millisecond Length: 26 Characters Sortable: Lexicographical

What is a ULID? (Universally Unique Lexicographically Sortable Identifier)

A ULID is a modern 128-bit identifier designed to resolve the limitations of traditional UUIDs while remaining 100% binary-compatible with UUID storage. Proposed by Alizain Feerasta in 2016, ULID combines the time-ordered sorting of auto-incrementing integers with the decentralized generation of cryptographic UUIDs.

Unlike standard UUIDs that require 36 characters with hyphens (e.g. f47ac10b-58cc-4372-a567-0e02b2c3d479), a ULID is encoded into 26 alphanumeric characters using Crockford's Base32 (e.g. 01ARZ3NDEKTSV4RRFFQ69G5FAV), making it compact, case-insensitive, and clean for HTTP URLs and REST APIs.

Anatomy & Bit Layout of a ULID

A ULID consists of two distinct components totaling 128 bits (16 bytes):

Component Character Count Bit Width Description
Timestamp 10 characters 48 bits Big-Endian Unix Epoch timestamp in milliseconds. Supports dates up to year 10,889 AD without wrapping.
Randomness 16 characters 80 bits Cryptographically secure pseudo-randomness (CSPRNG) generated via crypto.getRandomValues().
Total 26 characters 128 bits Encoded using Crockford's Base32. Completely URL-safe with zero hyphens or punctuation.

Why Crockford's Base32?

Crockford's Base32 alphabet uses characters 0123456789ABCDEFGHJKMNPQRSTVWXYZ. This encoding was chosen specifically over Hexadecimal or Base64 for three critical reasons:

  • Human Error Prevention: Excludes letters I, L, O, and U to eliminate reading ambiguity with numbers 1 and 0.
  • Accidental Profanity Defense: Excluding letter U prevents the unintentional generation of offensive words in public-facing identifiers.
  • Case Insensitivity: Both uppercase (01ARZ...) and lowercase (01arz...) parse to identical binary values, preventing database collation bugs.

ULID vs. UUID v4 vs. UUID v7: Feature Comparison

The table below summarizes the key trade-offs between ULID, legacy random UUIDv4, and the modern IETF RFC 9562 UUIDv7:

Metric ULID UUID v7 UUID v4
String Length 26 characters 36 characters 36 characters
Encoding Crockford's Base32 Hexadecimal (8-4-4-4-12) Hexadecimal (8-4-4-4-12)
Hyphens None (URL-friendly) 4 Hyphens 4 Hyphens
Lexicographical Sorting Yes (Natural string sort) Yes (Hex string sort) No (Random)
Timestamp Precision 1 millisecond (48 bits) 1 millisecond (48 bits) None
Standard Status Open Community Spec IETF RFC 9562 IETF RFC 4122
B-Tree Index Locality Optimal (Append-mostly) Optimal (Append-mostly) Poor (Page splits)

Sub-Millisecond Monotonicity

When high-throughput systems generate multiple ULIDs within the same millisecond, a standard random generator might yield non-sequential values. Monotonic ULID implementations detect multiple calls within the identical timestamp and increment the 80-bit random component by 1. This ensures that every newly minted ULID remains strictly greater than its predecessor.

Production Code Implementation Library

// Node.js / TypeScript: npm install ulidx
import { ulid, monotonicFactory } from 'ulidx';

// Standard ULID
const id = ulid();
console.log(id); // e.g. "01ARZ3NDEKTSV4RRFFQ69G5FAV"

// Monotonic ULID for guaranteed sorting in the same millisecond
const monotonicUlid = monotonicFactory();
const id2 = monotonicUlid();

Frequently Asked Questions About ULID

Yes. You can store a ULID as a VARCHAR(26) string column for maximum readability and URL compatibility. Alternatively, you can decode the 26 Base32 characters into standard 16 bytes and store it inside a native UUID column in PostgreSQL or a BINARY(16) column in MySQL, saving 10 bytes per row.

Yes. The 80-bit random component is generated using cryptographically secure pseudo-random number generators (such as crypto.getRandomValues in browsers and Node.js or /dev/urandom in operating systems). However, because the timestamp reveals the creation time, do not use ULIDs as secret authentication tokens or passwords.

With 80 bits of cryptographic entropy, a single node would need to generate over 1 billion ULIDs within the exact same millisecond to have a 50% probability of collision (birthday problem). Monotonic generators completely prevent intra-millisecond collisions by incrementing the least significant random bits.

ULIDs are 10 characters shorter than UUIDs (26 vs 36), contain no hyphens, and use a URL-safe character set that requires no percent-encoding. Furthermore, selecting the text in a browser or terminal with a double-click selects the entire 26-character string cleanly, unlike hyphenated UUIDs.