ULID Generator

Generate lexicographically sortable ULIDs.

Private by design. Your input never leaves this browser. Conversions run locally on your device.

What this tool handles

  • Generates ULIDs: 26 Crockford base32 characters, a 48-bit timestamp followed by 80 random bits.
  • Lexicographic order matches creation order, which is what makes them usable as database keys.
  • Monotonic mode guarantees ordering within the same millisecond.
  • 1, 10 or 100 at a time.

When you would use it

  • Primary keys in an insert-heavy table — Random identifiers scatter inserts across the whole of a B-tree index. ULIDs ascend, so new rows land at the right-hand edge of the index the way an auto-increment key does.
  • Event ids that sort chronologically — Ordering an event table by its id column reproduces the order the events were written, which can save a secondary index on a created_at column.
  • Seeding fixtures with ordered ids — Generate a block of ids in one go and paste it straight into a fixture file. Sorting that column afterwards gives the same order back, which makes snapshot assertions stable.
  • Choosing between ULID and UUIDv7 — Both put the same 48-bit millisecond timestamp first and both sort by time. UUIDv7 is a genuine UUID — 36 hyphenated hex characters, registered in RFC 9562 — while a ULID is a 26-character token that a UUID column or library will not accept.

Common questions

Why are two ULIDs made in the same millisecond out of order?

They share their first ten characters and differ only in the random tail, so their relative order within that millisecond is arbitrary. Monotonic mode is what removes the ambiguity.

How does a ULID differ from a UUID v4?

A v4 UUID is 122 random bits with no time component, so two ids created a second apart sort no closer together than two created a year apart. A ULID also carries no hyphens, so it survives a URL or a filename without escaping.

Why Crockford base32 rather than base64?

The alphabet leaves out I, L, O and U, so a ULID cannot be misread as a look-alike character or spell an unfortunate word, and it decodes case-insensitively.

Where do the random bits come from?

From crypto.getRandomValues, the platform CSPRNG, not Math.random — the ULID library's own random source is replaced with an explicit Web Crypto one so it behaves the same in every context.

Related tools

Browse all 25 tools