ULID Generator

Generate ULIDs online: 26-character Crockford Base32 IDs with 48-bit time and 80 random bits.

Format
Generated IDs
Ready. Generate ULIDs in your browser.

How this ID is built

Layout
26 Crockford Base32 characters: 10 time characters followed by 16 random characters.
Entropy
80 random bits after the 48-bit millisecond timestamp.
Time
Yes. The first 10 characters encode millisecond time, and lexical order follows time.
Collision risk
The random tail has 80 bits; risk is mainly about how many IDs you create in the same millisecond.
Example
01M12BRNY7D5GBEYVMQXFQEB2C

Your IDs are generated locally with strong browser randomness. Nothing is sent to BroBroGo.

FAQ

What is ULID good for?

ULID is compact, URL-friendly and time-sortable as plain text, which is useful for logs, object keys and records that should sort by creation time.

Is ULID the same as UUID v7?

No. Both include millisecond time, but ULID uses Crockford Base32 and 26 characters, while UUID v7 keeps the standard UUID hexadecimal shape.

What ULID Is and How This Page Works

The page generates universally unique lexicographically sortable identifiers (ULIDs) on demand. You set the count between 1 and 100, and the tool returns a list of 26‑character strings. Each string begins with a millisecond‑precision timestamp encoded as the first ten characters, followed by a 16‑character random suffix — 128 bits in total.

What distinguishes this page from sibling identifier generators (UUID, NanoID) is the combination of properties ULID brings: shorter than UUIDv4 (26 vs. 36 characters), case‑insensitive, hyphen‑free, and lexicographically sortable by creation time. The tool does not offer toggles for uppercase or hyphens, because ULID’s design already eliminates those choices. Every generated ID uses Crockford’s base32 alphabet (0–9, A–Z minus I, L, O, U), so there is no ambiguity between 1 and l, 0 and O, or similar visual confusions. All generation happens locally in the browser via crypto.getRandomValues(); nothing is transmitted to a server.

Internal Structure: Timestamp and Random Components

A ULID is a 128‑bit value packed into 26 characters. The breakdown is:

Component Bits Characters Encoding
Timestamp 48 10 Crockford base32
Random 80 16 Crockford base32

The timestamp is the number of milliseconds since the Unix epoch (1970‑01‑01T00:00:00Z), encoded in base32. Because the most significant bits appear first, two ULIDs generated at different times will sort lexicographically in chronological order when compared as strings. This is the key property that makes ULID useful for database primary keys and event logs where insertion order should roughly follow creation order.

The random component provides 80 bits of entropy, or 2^80 possible values per millisecond. The page uses crypto.getRandomValues() to fill a Uint8Array of 10 bytes, then converts those bytes into the Crockford‑encoded suffix. Because the timestamp is encoded first, ULIDs generated in the same millisecond will still differ in the random part but will not have a guaranteed monotonic order among themselves — the random component is not required to increase. (That lack of strict monotonicity within a millisecond is an explicit design trade‑off; some implementations add a monotonic counter, but the basic specification and this page do not.)

Why Crockford Base32 Makes ULIDs Human-Friendly

Crockford’s base32 encoding, defined by Douglas Crockford in 2005, is the alphabet behind ULID. The character set is:

0 1 2 3 4 5 6 7 8 9
A B C D E F G H J K M N P Q R S T V W X Y Z

Note the omissions: I, L, O, U. Why? I and 1 are easily confused; L and 1 also look similar in many fonts; O and 0 are indistinguishable; U might be mistaken for V in handwriting. By excluding these four letters, Crockford’s alphabet minimises transcription errors — a critical advantage when humans must read, copy, or dictate identifiers.

The alphabet is case‑insensitive: 'a' and 'A' decode to the same value. This means a ULID can be written entirely in lowercase, entirely in uppercase, or mixed, and still be interpreted correctly. The tool outputs them in uppercase by convention, but you could feed them in lowercase to any ULID‑aware system and it would accept them.

The lack of hyphens in ULID is deliberate — the 26 characters are packed without separators. While UUIDs use hyphens to break the 36‑character string into groups, ULID’s shorter length makes hyphens unnecessary. The entire string fits in a single token that is URL‑safe without any percent‑encoding (all characters are from the unreserved set defined in RFC 3986).

ULID vs UUID: Length, Sortability, and Use Cases

UUIDv4 (the most common variant) is 36 characters with hyphens and case‑insensitive only if you ignore the standard — officially UUIDs are presented in lowercase, but many systems treat them case‑insensitively. UUIDv7, a newer proposal, includes a timestamp and is also sortable, but it is not yet widely deployed. The tool on this page covers only UUIDv4 as an alternative.

Property ULID UUIDv4
Length (chars) 26 36 (including 4 hyphens)
Bits 128 122 random + 6 version
Sortable Yes (by creation time) No (random)
Case sensitivity Insensitive by design Typically insensitive but not guaranteed in all implementations
Hyphen separation No Yes (8‑4‑4‑4‑12 pattern)

For a primary key in a B‑tree index, random UUIDv4 values cause page splits because new keys can land anywhere in the tree. ULIDs, because they are monotonically increasing over time, insert near the right edge of the index, reducing rebalancing overhead. For applications that produce fewer than 1000 IDs per second, the ordering is effectively chronological. At higher rates, IDs generated in the same millisecond are unordered among themselves but still appear as a block after the previous millisecond’s block.

ULID’s 26‑character string is also 28 % shorter than a UUID’s 36‑character string. When stored as a string, this saves space; when stored as binary (16 bytes), both are identical in storage cost. In API responses, the shorter string reduces payload size.

Collision Probability and the Limits of Monotonic Ordering

With 80 bits of randomness per millisecond, the probability of a collision within a single millisecond is extremely low. The birthday problem tells us that you would need to generate roughly 2^40 (about 1 trillion) IDs in the same millisecond to have a 50 % chance of a collision. In practice, even at 10,000 IDs per millisecond, the collision probability is negligible.

However, the tool is limited to generating 100 IDs at a time, and each batch uses fresh randomness. If you generate multiple batches in the same millisecond, the timestamps will be identical, and the random suffixes will be independent — no guarantee of ordering between batches. The page does not attempt to enforce a within‑millisecond sequence.

A common misconception is that ULID guarantees global monotonic ordering across all generators. It does not. Two different machines with unsynchronised clocks could produce timestamps that are out of order relative to wall‑clock time. Even on a single machine, system clock adjustments (e.g., NTP corrections or leap seconds) can cause timestamps to jump backward, breaking the sort order. The tool sidesteps this by generating IDs on the user’s device, where the timestamp comes from Date.now() — subject to the device’s local clock accuracy.

URL Safety and Database Indexing Considerations

Every character in Crockford base32 (digits and the selected consonants) is unreserved in RFC 3986 — no need to percent‑encode when placing a ULID in a URL path, query parameter, or fragment. This contrasts with UUID’s hyphens, which are not reserved but can cause ambiguities in certain contexts (e.g., inside path segments that already use hyphens as separators). ULID’s compact string also fits comfortably in 32‑character database column limits if you choose CHAR(26).

For database indexing, ULID’s time sorting provides insertion locality. However, there is a subtlety: because the timestamp occupies the first 10 characters, a standard lexicographic sort on the string is equivalent to a sort by timestamp. But if you store the ULID as a 16‑byte binary value, the byte order may differ from string order unless you encode with the same big‑endian byte layout. ULIDs are lexicographically sortable by creation time as strings; the tool outputs strings, so any database column that sorts by string comparison will work as expected.

One more edge case: the timestamp uses 48 bits, which will overflow in the year 10889 AD (2^48 milliseconds ≈ 8925 years from the Unix epoch). For all practical systems, that is irrelevant.

Frequently Asked Questions

1. Can I generate more than 100 ULIDs at once?
No. The count field accepts only values between 1 and 100 inclusive. If you need more, generate multiple batches.

2. Are the ULIDs generated truly random?
Yes. The random suffix is produced using crypto.getRandomValues(), which is cryptographically strong. The timestamp is taken from Date.now(). All generation is local.

3. Why is there no option to add hyphens or change case?
ULID is designed without hyphens and is case‑insensitive by specification. Adding hyphens would break the standard representation; changing case has no effect on decoding. The tool respects the format as defined.

4. What happens if I generate IDs on a device with a wrong clock?
The timestamp will be incorrect relative to UTC, but the IDs will still be unique (due to the random component). They will sort according to the device’s clock, not real time. If clock accuracy matters, synchronise the device’s time via NTP.

5. Can two different users generate the same ULID?
In theory yes, but probability is negligible given the 80‑bit random space. The specification relies on the combination of timestamp (unique per millisecond) and randomness; collisions between independent generators are astronomically unlikely.

6. Is ULID better than UUID for every application?
No. If you need strict monotonic ordering within a millisecond (e.g., for event sourcing), ULID’s basic form does not guarantee it — you would need a variant with a per‑millisecond counter. If you must avoid any temporal information exposure (e.g., in publicly visible IDs), a full random UUIDv4 is preferable because ULID reveals the creation timestamp in the first ten characters.