Skip to content

Free ULID Generator — Generate, Decode & Convert ULIDs

Generate, decode, and convert ULIDs online — free and 100% in your browser. Extract the embedded timestamp from any ULID, convert ULID to UUID and back, batch-generate, with a monotonic mode. Nothing is ever sent to a server.

No Tracking Runs in Browser Free
Every ULID is generated locally with your browser’s cryptographic RNG (crypto.getRandomValues). Nothing is uploaded, logged, or stored.

Each ULID uses fresh 80-bit randomness.

What is a ULID?

A ULID — Universally Unique Lexicographically Sortable Identifier — is a 128-bit identifier created to fix a practical weakness of the random UUIDv4 while keeping its best property: you can generate one anywhere, with no central coordinator, and be confident it is unique. The difference is that a ULID is sortable by time. It is rendered as 26 characters of Crockford's Base32, split into two parts: the first 10 characters are a 48-bit timestamp counting milliseconds since the Unix epoch, and the last 16 characters are 80 bits of cryptographically secure randomness. Put the time first, encode it in an order-preserving alphabet, and the identifier sorts chronologically as a plain string.

That single design choice has outsized consequences for databases. A random UUIDv4 primary key lands in an unpredictable spot in a B-tree index on every insert, which fragments the index, thrashes the cache, and slowly degrades write performance as a table grows. A ULID, because it is time-prefixed, lands at or near the end of the index every time — inserts stay sequential, the index stays compact, and range scans over a time window become cheap. You get the coordination-free generation of a UUID and the insert locality of an auto-incrementing integer, without exposing a guessable sequential counter.

The encoding details are deliberate. Crockford's Base32 excludes the letters I, L, O, and U, both to avoid visual confusion with the digits 1 and 0 and to make the string case-insensitive on input. The result is 26 characters with no hyphens that are safe to drop into a URL, a filename, or a request header without escaping — noticeably shorter than a UUID's 36-character hyphenated form. The 48-bit timestamp does not run out for a long time: it can represent dates through the year 10889 before the millisecond counter overflows.

ULIDs are not the right tool for everything. The embedded timestamp reveals when a record was created, which is a feature for debugging and ordering but a small information leak if you would rather not expose that. And if your stack is committed to the UUID type, you may prefer UUIDv7, which applies the same time-prefixed idea inside the standard UUID format. But when you want short, URL-safe, sortable identifiers that you can mint on any node and read a timestamp back out of, a ULID is an excellent default — and because it is just 128 bits, you can always convert it to and from a UUID with this tool's Convert tab.

// Browser / Node with the `ulid` package
import { ulid, decodeTime } from 'ulid';

const id = ulid();          // e.g. 01KVT0F720ZK9N4T2QX7VR8WMC
const ts = decodeTime(id);  // 1782210600000  ->  2026-06-23T10:30:00.000Z

// Monotonic factory: strictly increasing within the same millisecond
import { monotonicFactory } from 'ulid';
const next = monotonicFactory();
next(1782210600000); // 01KVT0F720ZK9N4T2QX7VR8WMC
next(1782210600000); // 01KVT0F720ZK9N4T2QX7VR8WMD
next(1782210600000); // 01KVT0F720ZK9N4T2QX7VR8WME

Key features

Generate, Decode, and Convert in One Page

Three tabs cover the whole ULID workflow: mint new ULIDs, decode an existing one to read its timestamp, and convert losslessly between ULID and UUID. Most competing tools do only the first; here the full round trip lives on a single page.

Timestamp Decoder

Paste any ULID and read the exact millisecond it was created — shown in UTC, in your local time, and as raw Unix milliseconds — plus the 80-bit randomness segment. Audit when an identifier was minted with no database lookup.

Lossless ULID ↔ UUID Conversion

A ULID and a UUID are both 128 bits, so conversion is exact and reversible. The Convert tab auto-detects which format you pasted and produces the other, letting you bridge a sortable ULID and a UUID-typed column or API without losing a single bit.

Monotonic Mode

Need strict ordering even for IDs created in the same millisecond? Monotonic mode increments the randomness so each ULID is guaranteed greater than the last, keeping a tight insert loop perfectly sorted.

Batch Generation

Create up to 50 ULIDs at once and copy the whole set with Copy All. Ideal for seeding test fixtures, bulk inserts, or populating a lookup table without clicking fifty times.

Custom Timestamp

Embed a specific moment instead of now — useful for deterministic test data or for back-dating records during a migration while preserving the sortable property.

Cryptographically Secure Randomness

The 80 random bits come from crypto.getRandomValues, the browser's CSPRNG — never Math.random — so each ULID is unpredictable and same-millisecond collisions are vanishingly unlikely.

100% Private, Browser-Only

Every ULID is generated, decoded, and converted entirely on your device. No network requests, no logging, no storage — verify it yourself in DevTools → Network. Identifiers never reach a third party.

ULID examples

Generate a single ULID

Mode: Standard · Quantity: 1
01KVT0F720ZK9N4T2QX7VR8WMC

A ULID is 26 characters of Crockford's Base32. The first 10 characters encode a 48-bit millisecond timestamp and the last 16 encode 80 bits of cryptographically secure randomness drawn from crypto.getRandomValues. Because the timestamp comes first and Base32 preserves byte order, ULIDs generated later always sort after earlier ones as plain strings — no separate index needed. Click Copy to grab the value; click Generate again for a fresh one.

Decode a ULID to read its timestamp

01ARYZ6S41TSV4RRFFQ69G5FAV
Timestamp (UTC): 2016-07-30T22:36:16.385Z · Randomness: TSV4RRFFQ69G5FAV

Decode reverses the first 10 characters back into the 48-bit millisecond value embedded at creation time — here 1469918176385 ms, which is 2016-07-30T22:36:16.385Z. This is the canonical example from the ULID specification. The Decode tab shows the timestamp in UTC and your local time, the raw Unix milliseconds, and the 80-bit randomness segment, so you can audit exactly when an identifier was minted without any database lookup.

Convert a ULID to a UUID

01KVT0F720ZK9N4T2QX7VR8WMC
019ef407-9c40-fcd3-5268-57e9f784728c

A ULID and a UUID are both exactly 128 bits, so the conversion is lossless and fully reversible — the same bits are simply re-encoded from Crockford's Base32 into hyphenated hexadecimal. The Convert tab auto-detects whether you pasted a ULID or a UUID and converts to the other form. This lets you store ULIDs in a UUID column or hand a ULID to a system that only speaks UUID, then convert back when you need the sortable string again.

Batch-generate monotonic ULIDs

Mode: Monotonic · Quantity: 3 (same millisecond)
01KVT0F720ZK9N4T2QX7VR8WMC
01KVT0F720ZK9N4T2QX7VR8WMD
01KVT0F720ZK9N4T2QX7VR8WME

When many IDs are created inside the same millisecond, plain ULIDs share the 10-character time prefix but their random tails are unordered. Monotonic mode fixes this: within one millisecond it increments the previous randomness by one, so each ULID is strictly greater than the last and a batch stays perfectly sorted. Notice the three values differ only in the final character (C, D, E) — ideal for high-throughput inserts where ordering must hold even at sub-millisecond rates.

Generate a ULID for a specific date

Custom time: 2026-06-23 10:30:00 UTC
01KVT0F720… (time component 01KVT0F720)

Set a custom timestamp and the generator embeds that exact moment instead of now, while still filling the randomness from a secure RNG. The 10-character time component for 2026-06-23T10:30:00.000Z is 01KVT0F720. This is useful for seeding test fixtures with deterministic, time-ordered identifiers, or for back-dating records in a migration while keeping the sortable property intact.

How to use the ULID generator

  1. 1

    Pick a generation mode

    Standard mode gives each ULID fresh 80-bit randomness. Monotonic mode guarantees that ULIDs created within the same millisecond are strictly increasing — choose it for high-throughput inserts where ordering must hold even at sub-millisecond rates.

  2. 2

    Set quantity, case, and (optionally) a custom time

    Generate from 1 to 50 ULIDs at once. Output is UPPERCASE by default — the canonical ULID form — or switch to lowercase. Leave the time empty to stamp now, or set a custom timestamp to embed a specific moment for fixtures or back-dated records.

  3. 3

    Generate and copy

    Click Generate ULID. Use Copy on any single value, or Copy All to grab the whole batch as newline-separated text ready to paste into code, a seed file, or a spreadsheet.

  4. 4

    Decode a ULID to read its timestamp

    On the Decode tab, paste any ULID to extract the 48-bit creation timestamp in UTC and local time, the raw Unix milliseconds, and the 80-bit randomness — entirely in your browser, no lookup required.

  5. 5

    Convert between ULID and UUID

    On the ULID ↔ UUID tab, paste a ULID or a UUID; the tool auto-detects the input and converts to the other format losslessly. Store ULIDs in UUID columns, or hand a ULID to a UUID-only system and convert back when you need the sortable string.

Common Errors

Treating same-millisecond ULIDs as ordered

Plain ULIDs created within one millisecond share the time prefix but have unordered random tails, so their relative order is undefined. If you depend on strict ordering at that rate, use monotonic mode instead.

✗ Wrong
Standard mode, 3 IDs in one ms  →  order within the ms is random
✓ Correct
Monotonic mode, 3 IDs in one ms  →  …WMC < …WMD < …WME

Expecting a converted ULID to be a valid UUIDv4

Converting a ULID to UUID form re-encodes the same 128 bits; it does not set the UUID version and variant fields. The result is a valid 128-bit UUID string but will not report as version 4 or 7 if a library inspects those bits.

✗ Wrong
uuid.version(ulidToUuid(id))  →  not 4 (bits are the ULID's)
✓ Correct
Treat it as an opaque 128-bit value, or generate a real UUIDv7 instead

Using lowercase i, l, o in a ULID by hand

Crockford's Base32 excludes I, L, O, and U. Decoders map I and L to 1 and O to 0, but hand-typing those letters into a ULID is error-prone. Copy ULIDs rather than retyping them.

✗ Wrong
01ARYZ6S41TSV4RRFFQ69G5FAO  →  ambiguous O
✓ Correct
01ARYZ6S41TSV4RRFFQ69G5FAV  →  canonical characters only

What ULIDs are used for

Database Primary Keys That Stay Sorted
Use ULIDs as primary keys to get the coordination-free generation of a UUID with the insert locality of an auto-increment integer. Because they are time-prefixed, new rows append near the end of a B-tree index instead of scattering like UUIDv4, keeping inserts fast and the index compact as the table grows.
Distributed Systems Without a Central Sequence
Generate identifiers on any node — service, edge worker, or client — with no shared counter and no collision coordination, yet still sort everything by creation time after the fact. ULIDs give microservices a unique, ordered key without a database round trip to allocate it.
Event Logs and Message IDs
Stamp events, log lines, or queue messages with monotonic ULIDs so they remain in strict chronological order even when many are produced inside the same millisecond. Range-scanning a time window becomes a simple string comparison.
URL-Safe Public Identifiers
A ULID is 26 characters with no hyphens and a URL-safe alphabet, so it drops into a path, a filename, or a header without escaping and is shorter than a 36-character UUID. Decode the embedded timestamp later to see when the resource was created.
Bridge to a UUID-Only System
Working with a database column or an API that only accepts UUIDs? Generate sortable ULIDs, convert them to UUID form for storage or transport, and convert back when you need the compact sortable string — the 128-bit value is preserved exactly in both directions.
Deterministic Test Fixtures
Seed tests with ULIDs at chosen timestamps using the custom-time option, so fixtures are reproducible and already time-ordered. Decode them in assertions to verify the creation time your code recorded.

How ULIDs work

128-Bit Layout: 48-Bit Time + 80-Bit Randomness
A ULID is exactly 128 bits. The high 48 bits are a millisecond Unix timestamp; the low 80 bits are random. Encoded in Crockford's Base32 at 5 bits per character, that is 10 characters for the time and 16 for the randomness — 26 characters total. The leading character is always 7 or lower because 48 bits do not fill the top 5-bit group.
Crockford's Base32 Encoding
ULIDs use Crockford's Base32 alphabet (0–9 and A–Z excluding I, L, O, and U). Dropping those four letters avoids confusion with the digits 1 and 0 and lets decoders treat the string case-insensitively, mapping I and L to 1 and O to 0 on input. The alphabet is ordered, which is what makes the encoded string sort the same way as the underlying bits.
Lexicographic Sortability
Because the timestamp is the most significant component and the Base32 alphabet preserves order, comparing two ULIDs as strings yields the same result as comparing their 128-bit values, which yields the same result as comparing their creation times. This is what lets a plain ORDER BY or array sort produce chronological order with no extra index.
Monotonicity Within a Millisecond
The ULID spec's monotonic option keeps ordering stable for IDs minted in the same millisecond: the randomness of the first ID in a millisecond is generated normally, and each later ID in that millisecond is the previous random value plus one. This tool implements that by incrementing the 80-bit randomness as a big-endian integer.
Secure Randomness via crypto.getRandomValues
The 80 random bits are filled from crypto.getRandomValues, the Web Crypto CSPRNG, not Math.random. With 80 bits of entropy, generating even millions of ULIDs in the same millisecond keeps the collision probability negligibly small.
ULID ↔ UUID Is a Pure Re-Encoding
Converting between ULID and UUID does not change any bits — it re-encodes the same 128 bits from Crockford's Base32 to hyphenated hexadecimal or back. As a result the round trip is exact: a ULID converted to a UUID and back is byte-for-byte identical to the original. Note that a ULID's bytes do not set the UUID version and variant fields, so the resulting UUID is a valid 128-bit value but not a version-tagged UUIDv4 or v7.

ULID best practices

Use Monotonic Mode for High-Throughput Inserts
If your system can create more than one identifier per millisecond and you rely on ordering, generate monotonic ULIDs. Plain ULIDs are unordered within a millisecond; monotonic ones are strictly increasing, so a batch stays sorted no matter how fast you mint them.
Store ULIDs Compactly
A ULID is 128 bits — store it as 16 binary bytes or a UUID-typed column rather than as a 26-character text field when space and index size matter. Convert to the Base32 string only at the edges where humans or URLs see it. This tool's Convert tab gives you the UUID form for storage.
Remember the Timestamp Is Visible
A ULID reveals its creation time to anyone who can read it. That is great for debugging and ordering, but if exposing creation time is a concern — say, in a public-facing identifier — weigh that leak, or use a fully random UUIDv4 where ordering does not matter.
Always Generate with a CSPRNG
The uniqueness guarantee depends on the 80 random bits being unpredictable. Use a cryptographically secure source like crypto.getRandomValues, as this tool does — never Math.random, whose predictability could let identifiers collide or be guessed.
Pick ULID or UUIDv7 Deliberately
Both give time-ordered 128-bit IDs. Choose ULID for the shortest URL-safe string; choose UUIDv7 when you must stay in the standard UUID format with version and variant bits. Standardize on one per system, and use the Convert tab when you need to cross the boundary.

ULID — frequently asked questions

What is a ULID?
A ULID (Universally Unique Lexicographically Sortable Identifier) is a 128-bit identifier designed as a more sortable, more compact alternative to a UUID. It is written as 26 characters of Crockford's Base32: the first 10 characters hold a 48-bit timestamp in milliseconds since the Unix epoch, and the remaining 16 characters hold 80 bits of randomness. Because the timestamp is the most significant part and Base32 preserves order, ULIDs created later always sort after earlier ones when compared as plain strings — so a column of ULIDs is naturally time-ordered. The Crockford alphabet deliberately excludes the letters I, L, O, and U to avoid confusion with digits and to keep the string case-insensitive and URL-safe. ULIDs were introduced to solve a practical problem with random UUIDv4: random identifiers scatter across a database index, hurting insert performance, whereas a time-prefixed ULID lands near the end of the index every time.
ULID vs UUID — which should I use?
Use a ULID when you want identifiers that are both unique and naturally sortable by creation time; use a classic UUIDv4 when you specifically need an opaque, fully random identifier with no embedded timestamp. The key differences: a ULID is 26 characters of Base32 versus a UUID's 36 characters with hyphens, so ULIDs are shorter and URL-safe without escaping. A ULID encodes its creation time, which a UUIDv4 does not — useful for ordering and debugging, but worth noting if you would rather not expose when a record was made. Both are 128 bits and both avoid coordination, so collision risk is negligible for either. If your stack standardizes on UUIDs but you still want time-ordering, UUIDv7 (from the UUID Generator) offers a similar time-prefixed design in UUID format — or you can generate ULIDs here and convert them to UUID with the Convert tab.
Are ULIDs sortable?
Yes — that is the defining feature. Because the 48-bit millisecond timestamp occupies the first 10 characters and Crockford's Base32 preserves lexicographic order, sorting ULIDs as ordinary strings sorts them by creation time. This holds in any system that compares strings byte by byte: a database ORDER BY, a sorted set, a file listing, or a simple array sort. The practical payoff is database performance: time-ordered keys append to the end of a B-tree index instead of scattering randomly like UUIDv4, which keeps inserts fast and the index compact. Within a single millisecond the ordering of plain ULIDs is random, so if you need strict ordering even for IDs minted in the same millisecond, use the monotonic mode, which increments the randomness so each value is guaranteed greater than the last.
How do I decode a ULID's timestamp?
Paste the ULID into the Decode tab and the tool extracts the embedded creation time instantly, entirely in your browser. It reads the first 10 characters, converts them from Crockford's Base32 back to a 48-bit integer of milliseconds since the Unix epoch, and shows that moment in UTC and your local time along with the raw Unix-millisecond value. For example, the canonical ULID 01ARYZ6S41TSV4RRFFQ69G5FAV decodes to 1469918176385 ms, or 2016-07-30T22:36:16.385Z. The remaining 16 characters are the 80-bit randomness and carry no meaning to decode. Reading the timestamp this way is handy for debugging, auditing when a record was created, or sanity-checking that an identifier really is a ULID — no database query required.
What is a monotonic ULID?
A monotonic ULID guarantees strict ordering even for identifiers generated within the same millisecond. Plain ULIDs created in one millisecond share the same 10-character time prefix, but their 80-bit random tails are independent, so their relative order is not defined. Monotonic generation solves this: the first ULID in a given millisecond gets fresh randomness, and each subsequent ULID in that same millisecond is produced by incrementing the previous randomness by one. The result is a sequence where every value is strictly greater than the one before it, so a batch inserted in a tight loop stays perfectly sorted. This matters for high-throughput systems — event logs, message queues, bulk imports — where many rows can be created faster than the millisecond clock ticks and you still need a stable, increasing key.
Is this ULID generator secure and private?
Yes on both counts. The randomness in every ULID comes from crypto.getRandomValues, the browser's cryptographically secure random number generator — never Math.random — so the 80 random bits are unpredictable and the chance of two ULIDs colliding within the same millisecond is vanishingly small. Just as important, everything runs locally: the ULIDs are generated, decoded, and converted entirely on your device. Nothing is uploaded, logged, or stored, and you can confirm it by opening DevTools and watching the Network tab stay silent while you click Generate. That privacy property is the whole reason to create identifiers in the browser rather than on a server that could, in principle, keep a copy of every value it hands out.
What is the difference between ULID and UUIDv7?
Both ULID and UUIDv7 are time-ordered 128-bit identifiers that put a millisecond timestamp first, so both sort by creation time and both index efficiently — the core idea is the same. The difference is format and encoding. A ULID is presented as 26 characters of Crockford's Base32 with no hyphens, which is shorter and URL-safe; UUIDv7 is presented in the standard 36-character hyphenated hexadecimal UUID layout and carries version and variant bits in fixed positions, so it is a fully valid RFC 9562 UUID that any UUID library accepts. Choose UUIDv7 when you must remain in the UUID ecosystem (a UUID database column, a UUID-typed API); choose ULID when you want the shortest sortable string. Since both are 128 bits, you can generate a ULID here and convert it to UUID form with the Convert tab, or generate a UUIDv7 with the UUID Generator. For a deeper side-by-side of ULID, UUIDv4, UUIDv7, and Snowflake IDs, see our guide to sortable unique identifiers.

Related Tools

View all tools →