ULID Generator

Generate sortable, 26-character ULIDs (Crockford base32) and decode the embedded timestamp back to a date. Great for database primary keys.

Sortable unique identifiers. A ULID is 26 characters: the first 10 encode the creation time in milliseconds, the last 16 are random. That makes them lexicographically sortable and safe to use as keys. Generated in your browser.

ULID versus UUID

What a ULID is

A ULID is a 128-bit identifier, the same width as a UUID, split into two parts: a 48-bit millisecond timestamp followed by 80 random bits. It is rendered as 26 characters of Crockford base32 rather than the 36-character hyphenated hex of a UUID, so it is shorter, case-insensitive and free of the characters most easily misread — I, L, O and U are all excluded from the alphabet.

The consequential difference is not the encoding, it is the ordering. Because the timestamp occupies the high bits and base32 preserves byte order, sorting ULIDs as plain strings sorts them by creation time. Two IDs generated in the same millisecond fall back to their random component, but across milliseconds the order is exact.

Why sortability matters for databases

UUIDv4 is uniformly random, which is exactly what you do not want in a clustered index. Every insert lands at a random point in the B-tree, so the database keeps splitting pages and touching cold ones. The index grows larger than it needs to be and write throughput degrades as the table grows. This is a well-documented problem with UUID primary keys in MySQL's InnoDB and in SQL Server.

A time-ordered identifier appends near the right edge of the index, which is the same access pattern as an auto-increment integer. You keep the benefits of a client-generated globally unique key — no round trip to get an ID, no coordination between services, safe merges across shards — without the index fragmentation.

When to use something else

UUIDv7, standardised in RFC 9562, does the same thing as ULID in the standard UUID format and layout. If your stack already has native UUID column types and tooling, UUIDv7 is usually the better choice now simply because it drops into the existing ecosystem. ULID remains attractive when you want the shorter, friendlier text form in URLs or logs.

Either way, be clear that the timestamp is visible to anyone holding the ID. Creation times leak, and adjacent IDs reveal ordering — do not use these for anything where the enumeration or the timing is sensitive. And with 80 random bits per millisecond, collisions are not a practical concern, but ULIDs are not secrets and should never be used as capability tokens.

Open-source note: implemented with crypto.getRandomValues and a from-scratch Crockford base32 codec. No third-party libraries.

FAQ

How is a ULID different from a UUID?
Both are 128 bits, but a ULID puts a 48-bit millisecond timestamp first, so sorting the strings sorts by creation time. UUIDv4 is entirely random and sorts arbitrarily.
Why does sortability matter for a database?
Random primary keys scatter inserts across a B-tree and fragment the index. Time-ordered keys append near the end, which keeps writes sequential and the hot pages small.
Are IDs created in the same millisecond still ordered?
In monotonic mode, yes. Instead of redrawing the random part the tool increments it, so several IDs generated within one millisecond still come out in order.
Is a ULID safe to expose publicly?
The random half is unguessable, but the timestamp is readable by anyone. If the creation time of a record is sensitive, do not use a ULID as its public identifier.
Should I pick ULID or UUIDv7?
They solve the same problem. UUIDv7 is standardised in RFC 9562 and fits existing UUID columns and libraries, so prefer it for new work unless you specifically want the 26-character Crockford form.
Why 26 characters?
128 bits encoded in Crockford Base32 needs 26 symbols. The alphabet excludes I, L, O and U to avoid both transcription mistakes and accidental words.