ULID Generator
Universally Unique Lexicographically Sortable Identifier — 128 bits, 26 Crockford Base32 characters, sorted by creation time. The predecessor to UUID v7, still widely deployed and a fine choice when you want sortability without a UUID-shaped identifier.
Click Generate to produce ULIDs.
About ULID
ULID — Universally Unique Lexicographically Sortable Identifier — was specified in 2016 by Alizain Feerasta. It predates UUID v7 by eight years and was, in many ways, a precursor to v7's design: a time-ordered 128-bit identifier optimised for use as a database primary key and for lexicographic sortability.
A ULID is 26 characters in Crockford Base32 encoding. The first 10
characters encode a 48-bit Unix millisecond timestamp; the remaining 16
characters encode 80 bits of randomness. Crockford Base32 was chosen over
base64 because it's case-insensitive (the same ULID is valid in upper or
lower case) and excludes visually ambiguous characters (I,
L, O, U), making ULIDs more robust when
transcribed or read aloud. See the
ULID spec.
The format has substantial production use in Go, Node.js, and Rust ecosystems particularly. Library support exists for most major languages.
ULID versus UUID v7
The two formats solve essentially the same problem with similar tradeoffs. The differences are mostly stylistic:
- Encoding. ULID is 26 characters in Crockford Base32. UUID v7 is 36 characters in hyphenated hex. Both encode 128 bits.
- Case sensitivity. ULIDs are case-insensitive by design. UUIDs are case-insensitive in practice but conventionally lowercase.
- Ecosystem. UUID v7 has the weight of RFC 9562 behind it and native support in language runtimes is rapidly catching up (.NET 9, Go 1.23 via
google/uuid, etc.). ULID has older, more established library support across many ecosystems but no formal standard. - Random bits. UUID v7 has 74 random bits after the timestamp; ULID has 80. The practical difference is negligible.
- Monotonicity guarantees. ULID's specification includes an optional monotonic mode that increments the random component for IDs generated within the same millisecond, providing strict ordering. UUID v7's RFC discusses similar techniques but doesn't mandate them.
For new projects, the choice often comes down to ecosystem fit. If you're working in an environment where UUID is the natural primitive (most relational databases, most enterprise stacks), UUID v7 is the smoother choice. If you're working in an environment that already uses ULID or where the shorter URL-friendly form is valuable, ULID remains compelling. ULID, v7, Snowflake, and KSUID are all answers to the same underlying problem; for the wider comparison and a decision framework, see generating IDs in distributed systems.
Monotonic mode
By default, two ULIDs generated within the same millisecond have unrelated random components — they will sort, but in arbitrary order relative to each other. Monotonic mode addresses this by remembering the random component of the previous ULID generated within a given millisecond and incrementing it for the next one. This guarantees that consecutive ULIDs from the same generator are strictly ordered, even at sub-millisecond intervals.
Enable monotonic mode when:
- IDs are generated rapidly in batches and you need ordering within the batch;
- You're using the ULID's sort position as a tiebreaker for events that occurred in the same millisecond;
- You want to ensure that ID order matches generation order regardless of clock precision.
Default (non-monotonic) mode is sufficient when:
- IDs are generated infrequently relative to the millisecond precision;
- Approximate ordering is good enough;
- Multiple generators run in parallel (monotonic mode is per-generator and doesn't coordinate across instances).
Toggle the checkbox above to compare. Generate 100 ULIDs without monotonic mode — most will share a timestamp prefix but the random suffix scrambles ordering. Turn it on and they're in strict order.
Storage and interoperability
A ULID's 128-bit binary representation is the same size as a UUID's. Most databases that support UUIDs can store ULIDs in the same column type with conversion at the application boundary. This makes mixed UUID/ULID systems practical — the underlying storage is identical even though the textual representations differ.
Generating in code
JavaScript
import { ulid, monotonicFactory } from 'ulid'
const id = ulid()
const monoUlid = monotonicFactory()
const ordered = monoUlid()
C# (NUlid)
using NUlid;
var id = Ulid.NewUlid();
Python
from ulid import ULID
id = ULID()
FAQ
Should I pick ULID or UUID v7?
Can ULIDs be stored as UUIDs?
Is the ULID specification still maintained?
Why Crockford Base32?
I, L, O and
U — characters that are visually ambiguous or unfortunate.
That makes ULIDs safer to read out loud, transcribe, and copy without
error. The encoding is also case-insensitive on input
(I→1, L→1, O→0).