Each ULID sorts lexicographically in the order it was generated — the first 10 characters encode the millisecond timestamp.
How to Use ULID Generator
Set how many ULIDs you need (1-100) and press Generate. Each one encodes the current millisecond timestamp in its first 10 characters and 80 bits of cryptographic randomness in the remaining 16, using Crockford's base32 alphabet. Copy the batch with one click. Everything is computed in your browser with a small hand-written implementation — no external library.
About ULID Generator
A ULID (Universally Unique Lexicographically Sortable Identifier) solves a specific problem that UUID v4 does not: it needs to be both globally unique and sortable in the order it was created. A standard UUID v4 is almost entirely random, which is great for uniqueness but means a batch of UUIDs generated over time gives you no way to tell which came first without a separate "created_at" column. A ULID bakes a millisecond-precision timestamp directly into the front of the identifier, so sorting a list of ULIDs as plain text automatically sorts them by creation time — no extra column, no extra index, no extra query.
This matters more than it might first seem for database performance. Many databases store rows physically ordered (or indexed) by their primary key. If that key is a random UUID, every insert lands at a random point in the index, causing page splits and fragmentation that get worse as the table grows — a well-documented pain point for UUID-keyed tables at scale. A ULID primary key, being roughly time-ordered, inserts close to the end of the index most of the time, behaving much more like a traditional auto-incrementing integer while still being safe to generate on multiple machines independently without coordination. This is why ULIDs (and similar time-sortable ID schemes like Twitter's Snowflake or Stripe's newer object IDs) have become popular for high-throughput systems that still want the distributed-generation benefits UUIDs offer.
A ULID is 26 characters long, encoded in Crockford's base32 — a variant of base32 that deliberately excludes the letters I, L, O and U. Those four are dropped because they are easy to confuse with other characters when read or typed by hand: I and L can look like the digit 1, O can look like the digit 0, and U was additionally excluded to avoid accidentally spelling profanity when random characters happen to line up. The remaining 32-character alphabet (0-9 and A-Z minus I, L, O, U) means every character unambiguously represents one of 32 values, and the encoding is also case-insensitive-safe by convention (though this tool defaults to uppercase, matching the ULID specification, with a lowercase option available).
The first 10 characters encode a 48-bit millisecond timestamp — enough range to represent dates far beyond the year 10889, so it will not run out any time soon. The remaining 16 characters encode 80 bits of randomness generated fresh for every ID with `crypto.getRandomValues()`, the same cryptographically secure randomness source used elsewhere in this tools category. Two ULIDs generated in the same millisecond will still differ (and be effectively impossible to guess) because of that randomness — only their sort order becomes ambiguous relative to each other within that single millisecond, which is rarely a practical problem.
Details & Tips
Anatomy of a generated ULID, e.g. `01ARZ3NDEKTSV4RRFFQ69G5FAV`: the first 10 characters (`01ARZ3NDEK`) are the base32-encoded millisecond timestamp — every ULID generated later in time will sort after this one purely as a text string, because base32 digit ordering preserves numeric ordering. The remaining 16 characters (`TSV4RRFFQ69G5FAV`) are 80 bits of fresh cryptographic randomness, giving the same practical collision resistance within a millisecond that UUID v4 gives across its whole range.
Why Crockford's base32 specifically: it packs more information per character than hexadecimal (5 bits per character versus 4), which is why a ULID (26 characters) is shorter than the hex-with-hyphens UUID format (36 characters) while encoding a comparable amount of information, plus a timestamp UUID v4 does not carry at all. Removing the ambiguous I/L/O/U characters also makes ULIDs noticeably easier to read aloud, copy by hand, or spot a typo in compared with mixed-case hexadecimal.
When to prefer a ULID over a UUID v4: use a ULID when you want IDs to double as a rough "created before/after" signal, when you are choosing a primary key for a high-write-volume database table and want to avoid the index fragmentation random UUIDs cause, or when you want a shorter, more copy-paste-friendly identifier than a hyphenated UUID. Use UUID v4 instead when you specifically do not want the identifier to leak any timing information — a ULID's first 10 characters reveal roughly when it was created, which is a form of information disclosure that matters in a small number of security-sensitive contexts (e.g. an identifier that should not hint at account creation order).
Compatibility notes: ULIDs are not a registered IETF standard the way UUIDs are (RFC 4122; a newer RFC 9562 also standardises UUID versions 6/7/8, which cover similar time-sortable ground within the UUID format itself), but the ULID specification is widely implemented across many languages and is a de facto standard in its own right. If your database or ORM does not have native ULID support, ULIDs are commonly stored as a 26-character `CHAR(26)` column, or converted to their equivalent 128-bit value and stored as a standard UUID/binary column when the schema requires that type.
Frequently Asked Questions
What does ULID stand for?
Universally Unique Lexicographically Sortable Identifier — an identifier format designed to be both globally unique like a UUID and sortable in creation order as a plain string, which a standard UUID v4 is not.
How is a ULID different from a UUID?
A UUID v4 is almost entirely random, so a batch of them carries no ordering information. A ULID replaces the first 48 bits with a millisecond timestamp, so sorting ULIDs as text automatically sorts them by creation time, while the remaining 80 bits stay fully random for uniqueness.
Why does the alphabet exclude I, L, O and U?
Crockford's base32, which ULIDs use, drops those four characters because I and L can be misread as the digit 1, O can be misread as 0, and U is additionally excluded to reduce the chance of accidental offensive strings appearing at random.
Are two ULIDs generated in the same millisecond guaranteed to be unique?
Yes for all practical purposes — each still carries 80 bits of fresh cryptographic randomness, the same order of collision resistance as UUID v4 provides across its entire value. Only their relative sort order within that single millisecond becomes ambiguous.
Will ULIDs run out of timestamp space?
No — the 48-bit timestamp field can represent dates until roughly the year 10889, far beyond any practical concern.
Can I convert a ULID to a UUID?
Yes — both are 128-bit values under the hood, so a ULID can be re-encoded as a standard hyphenated UUID string (or stored in a native UUID/binary column) if your system requires that specific format; several libraries provide this conversion directly.
Why would I use a ULID as a database primary key instead of an auto-increment integer?
A ULID can be generated independently on any server without coordinating with a central counter, avoiding the bottleneck and single point of failure of auto-increment in distributed systems, while still inserting in roughly sorted order for good index performance — a middle ground between auto-increment integers and fully random UUIDs.
Does a ULID reveal when a record was created?
Yes — the first 10 characters directly encode the creation timestamp, so anyone who can decode Crockford base32 can extract roughly when the ID was generated. If that is a problem in your context (e.g. hiding account creation order), use a UUID v4 instead.
What generates the randomness in this tool's ULIDs?
`crypto.getRandomValues()`, the browser's cryptographically secure random number generator — the same class of source used for UUID v4 generation and other security-sensitive randomness, not the weaker `Math.random()`.
Is my data sent anywhere when I generate ULIDs?
No. The entire encoding — timestamp and randomness alike — happens locally in your browser with a small hand-written JavaScript implementation; nothing is transmitted or stored.
Can I generate a ULID for a specific past or future timestamp?
This tool always encodes the current moment. If you need a ULID for an arbitrary timestamp (useful for backfilling historical data), you would need a library or script that accepts a custom timestamp input rather than this generator, which is built for quick, current-time bulk generation.