Before UUID v7 was standardised in RFC 9562 (May 2024), ULID was the most popular way to get time-sortable, globally unique identifiers in distributed systems. Now that v7 has RFC status and PostgreSQL 18 support, the comparison is worth revisiting.

Side-by-Side Comparison

PropertyUUID v7ULID
Timestamp precision48-bit Unix milliseconds48-bit Unix milliseconds
Random bits74 bits80 bits
Total size128 bits128 bits
String format018f-be3a-… (36 chars, hex)01ARZ3NDEK… (26 chars, Base32)
RFC standardYes — RFC 9562No
DB native typeuuid (PostgreSQL, MySQL 8+)varchar or binary (custom)
PostgreSQL 18uuidv7() built-inExtension required
Monotonic counterOptional (RFC recommends)Yes — counter per millisecond
Case-sensitiveNoYes (Crockford Base32 is case-insensitive in spec, implementations vary)

Where ULID Has an Edge

Shorter strings. A ULID’s 26-character Base32 encoding is 28% shorter than a UUID’s 36-character hex string. In APIs that return IDs in JSON, or URLs that embed IDs, shorter strings reduce payload size.

More random bits. ULID uses 80 random bits vs UUID v7’s 74. The practical collision risk at any realistic generation rate is negligible for both, but ULID has a slight theoretical edge.

Human readability. Crockford Base32 avoids ambiguous characters (0 vs O, 1 vs I) and is easier to read aloud or transcribe than a hex UUID string.

Where UUID v7 Has an Edge

RFC standard. UUID v7 is defined by RFC 9562. ULID has no IETF standard — it is a community spec maintained on GitHub. Standards matter for long-lived systems, audits, and cross-vendor compatibility.

Native database type. PostgreSQL’s uuid type, MySQL 8’s UUID functions, and SQL Server’s uniqueidentifier all handle UUID v7 natively. ULID requires storing as varchar(26) or binary(16) with manual encoding/decoding.

PostgreSQL 18. The new uuidv7() built-in function means UUID v7 generation can be pushed entirely to the database layer — no application code required for inserts that go through raw SQL or migrations.

Ecosystem support. The uuid npm package, Python’s standard library, google/uuid for Go, and Hibernate 6.5 all support UUID v7. ULID has per-ecosystem community packages with varying maintenance status.

When to Choose ULID

When to Choose UUID v7

Frequently asked questions

Should I use UUID v7 or ULID for sortable IDs?

In 2026, UUID v7 is the better default. It has RFC standardisation (RFC 9562), native PostgreSQL 18 support, and stores in the existing uuid column type. ULID has no RFC standard and requires custom storage. Choose ULID only if shorter 26-char strings are important for your use case.

Should I use v4 or v7?

Use v7 for database primary keys (time-sortable, index-friendly) and v4 for anything where creation order could leak information, like tokens or share links.

What did RFC 9562 add to the UUID standard?

RFC 9562, published in May 2024, adds UUID v6 (reordered timestamp for sortability), v7 (Unix millisecond timestamp), and v8 (custom layout). It also defines the Max UUID sentinel (all-ones complement of the Nil UUID) and deprecates v1 and v2. The existing format and v3, v4, v5 semantics are unchanged.

What is a ULID?

A ULID (Universally Unique Lexicographically Sortable Identifier) is a 128-bit identifier with a 48-bit millisecond timestamp and 80 random bits, encoded as a 26-character Crockford Base32 string (e.g. 01ARZ3NDEKTSV4RRFFQ69G5FAV). It was designed to be a sortable, human-readable alternative to UUID v4 before UUID v7 was standardised.

Is UUID v7 better than ULID?

For most use cases in 2026, UUID v7 is the better choice. It is an RFC standard (RFC 9562), natively supported in PostgreSQL 18, and stores in the existing uuid column type without schema changes. ULID requires custom storage (varchar or binary) in most databases and has no RFC standard. ULID's Crockford Base32 encoding is more human-readable but adds implementation complexity.