48-bit time + 80-bit random

ULID generator

Generate identifiers that sort by the moment they were created, then decode any ULID back to its timestamp and randomness.

Up to 100 per run.

ULIDs are generated in this tab with the browser’s cryptographic random source. Nothing is sent anywhere.

Short answer: press Generate ULIDs for up to 100 sortable identifiers. Paste any ULID into the decode field to see when it was created and which part is randomness.

The two halves

The first ten characters are a 48-bit count of milliseconds since the Unix epoch — the same clock a Unix timestamp uses, just written in Base32. The last sixteen characters are 80 bits from the browser CSPRNG. That split is why01ARZ3NDEK… sorts before 01ARZ3NF1A…: the string comparison is comparing creation times.

When a ULID is the wrong choice

ULID questions

How is a ULID different from a UUID?

Both are 128 bits. A UUID v4 is pure randomness, so it carries no order; a ULID puts 48 bits of millisecond timestamp first and 80 bits of randomness after it. Sorted as strings, ULIDs are in creation order, which makes them good primary keys for databases that insert in time order.

Why do ULIDs look shorter than UUIDs?

Because Crockford Base32 spends 5 bits per character instead of 4, so 128 bits fit in 26 characters. The alphabet leaves out I, L, O and U so a value cannot be misread as a different one — the same reason VINs skip letters.

Are two ULIDs generated in the same millisecond ordered?

Not reliably. The specification has an optional monotonic mode that increments a counter inside the same millisecond, and this page does not implement it: the timestamp halves are identical and the randomness decides the order. If you need strict ordering inside one millisecond, keep a counter in your own database.

Can a ULID leak information?

Yes — the first 48 bits are the creation time to the millisecond, readable by anyone holding the identifier. That is usually the point (sortable keys, log correlation), but it is a disclosure: an ID tells people when the row was created. A UUID v4 does not.

Where does the randomness come from?

crypto.getRandomValues, the browser CSPRNG. Math.random is never used for an identifier here, and the page refuses to generate anything if that API is unavailable rather than falling back to something weaker.

Related tools