Anatomy of a ULID
01ARYZ6S41 TSV4RRFFQ69G5FAV
|----------| |----------------|
Timestamp Randomness
48 bits 80 bits
10 chars 16 chars
- Sortable: the timestamp comes first, so ULIDs sort by creation time as plain strings.
- Readable: Crockford Base32 leaves out I, L, O and U to avoid confusion. The decoder accepts lowercase and reads I/L as 1 and O as 0.
- URL-safe: no hyphens or special characters.
- Collision-resistant: 80 random bits per millisecond, which is 1.2 × 10²⁴ possibilities.
ULID vs UUID v4 vs UUID v7
| Feature | ULID | UUID v4 | UUID v7 |
|---|---|---|---|
| Size | 128 bits | 128 bits | 128 bits |
| Text length | 26 | 36 | 36 |
| Time-sortable | Yes | No | Yes |
| Embedded timestamp | ms | None | ms |
| Native DB type | No (use UUID or text) | Yes | Yes |
| Standard | Community spec | RFC 9562 | RFC 9562 |
Choose ULID when you want compact, human-friendly IDs in URLs and logs. Choose UUID v7 when your database or tooling expects standard UUIDs.
Generate ULIDs in code
JavaScript / TypeScript
// npm install ulid
import { ulid, decodeTime, monotonicFactory } from 'ulid';
ulid(); // "01JA8X6M2Q8Y3ZQ9W5C1N4R7TB"
decodeTime('01ARYZ6S41TSV4RRFFQ69G5FAV'); // 1469918176385
const next = monotonicFactory(); // strictly increasing within the same ms
next(); next();
Python
# pip install python-ulid
from ulid import ULID
u = ULID()
str(u) # '01JA8X6M2Q8Y3ZQ9W5C1N4R7TB'
u.datetime # datetime.datetime(..., tzinfo=datetime.timezone.utc)
u.to_uuid() # UUID('0192...')
Go
// go get github.com/oklog/ulid/v2
id := ulid.Make()
fmt.Println(id.String()) // 01JA8X6M2Q8Y3ZQ9W5C1N4R7TB
fmt.Println(ulid.Time(id.Time()))
Frequently asked questions
What is a ULID?
ULID stands for Universally Unique Lexicographically Sortable Identifier. It is a 128-bit ID made of a 48-bit millisecond timestamp and 80 bits of randomness, written as 26 Crockford Base32 characters such as 01ARYZ6S41TSV4RRFFQ69G5FAV.
ULID vs UUID: which should I use?
Both are 128 bits. ULIDs are time-sortable and shorter to write (26 vs 36 characters). Random UUID v4s are not sortable, which fragments database indexes. If you need a standard UUID type in your database, UUID v7 gives you the same time-ordering in UUID format.
Can I get the creation time from a ULID?
Yes. The first 10 characters encode the Unix timestamp in milliseconds. Paste any ULID into the decoder above to see it as UTC, local time and Unix time.
Can I store a ULID in a UUID column?
Yes. A ULID is 128 bits, the same as a UUID, so it converts losslessly. The decoder shows the UUID form, and pasting a UUID converts it back to a ULID. Note that the result will not have UUID version bits set.
Are the generated ULIDs secure?
The random part comes from your browser’s cryptographically secure generator (crypto.getRandomValues). In monotonic mode, IDs generated in the same millisecond increment the previous random value, so they are predictable relative to each other. Don’t use them as secret tokens.