UUID v7 vs ULID: Which Sortable ID Should You Use?
By SimpleTools24Published 4 min read
UUID v7 and ULID solve the same problem: unique IDs that sort by creation time. Both use a 48-bit millisecond Unix timestamp followed by random bits, and both are 128 bits long. The main differences are that UUID v7 is an IETF standard (RFC 9562) that fits every existing UUID column, library and API, while ULID is a community specification with a shorter, case-insensitive 26-character text form. For most new systems, UUID v7 is the safer default; ULID makes sense where compact, readable strings matter more than native UUID support.
In this guide
Side-by-Side
| UUID v7 | ULID | |
|---|---|---|
| Size | 128 bits | 128 bits |
| Timestamp | 48-bit Unix ms | 48-bit Unix ms |
| Random part | 74 bits (minus version/variant) | 80 bits |
| Text form | 36 chars, hex with hyphens | 26 chars, Crockford Base32 |
| Example | 0192f0c1-6a4b-7c3d-9e2f-0a1b2c3d4e5f | 01JBTX2SKBFG3SAKZ3JMZ0ZHQ7 |
| Standard | IETF RFC 9562 | Community spec on GitHub |
| Native DB type | uuid / uniqueidentifier | Usually stored as text or binary(16), or converted to UUID |
| Built-in generators | .NET 9, Python 3.14, PostgreSQL 18 | Libraries only |
| Monotonic within a ms | Optional methods in RFC | Spec defines monotonic increment |
Text Encoding
The most visible difference is the string:
- UUID v7 uses the familiar
8-4-4-4-12hexadecimal format with hyphens. Every UUID parser, validator and database understands it. - ULID uses Crockford's Base32, which avoids ambiguous letters (I, L, O, U), is case-insensitive and URL-safe, and takes only 26 characters. It's easier to read aloud and shorter in URLs.
Both sort lexicographically in creation order as text, because the timestamp is first and the encodings preserve order.
Standards and Interoperability
RFC 9562 makes UUID v7 a first-class UUID. You can put a v7 value in any uuid column, pass it to any API expecting a UUID, and validate it with existing tools. That's a strong practical advantage.
ULID isn't a UUID, though its 128 bits can be converted to and from UUID form for storage. Many teams store ULIDs as UUIDs in the database and render them as ULID strings in the application, which works but adds a conversion layer.
Monotonicity
Within a single millisecond, ordering depends on the random part:
- The ULID specification describes a monotonic mode: if a generator creates several ULIDs in the same millisecond, it increments the random part, so they sort in creation order.
- RFC 9562 describes optional methods for UUID v7, such as a counter in the
rand_abits or extra timestamp precision. Implementations choose whether to use them.
Neither guarantees order across different machines, whose clocks differ. What is UUID v7 covers the ordering limits.
Other Sortable IDs
- KSUID: 160 bits with a second-precision timestamp and 128 random bits; 27-character Base62 strings.
- Snowflake-style IDs: 64-bit integers combining a timestamp, machine ID and sequence; compact but require assigning machine IDs.
- UUID v6: a reordered version of v1 that's time-sortable but still carries v1's node field; RFC 9562 recommends v7 for new systems.
How to Choose
- Choose UUID v7 if you use native UUID columns, want standard tooling and built-in generators, or work across many languages and services.
- Choose ULID if compact, human-friendly strings in URLs or logs are important and you're happy to rely on libraries.
- Either way, keep a real timestamp column for business logic, and avoid exposing creation times publicly if that's sensitive.
If you're moving from random UUIDs, UUID v4 vs UUID v7 explains the benefits, and how to generate UUID v7 has code for each platform.
Try UUID v7
The UUID v7 generator creates standard v7 values in your browser, and the UUID decoder reads back their embedded timestamp, which is a quick way to see how the time prefix works before choosing a format.
Converting Between ULID and UUID
Both are 128-bit values, so libraries can convert between them:
- A ULID's 128 bits can be written in UUID text form for storage in a
uuidcolumn. - A UUID v7 can be rendered in Crockford Base32 for a shorter display form.
Note that a converted ULID won't have UUID version and variant bits set unless the library adjusts them, so strict UUID validators may reject it. If you need both forms, decide which is canonical and convert only at the edges.
Migration Considerations
Moving from ULID to UUID v7 (or the reverse) doesn't require changing existing IDs: both sort by time, so old and new values can coexist in the same column as long as they share a storage format. Update validators, document the change, and test any code that parses IDs.
Frequently Asked Questions
Is ULID better than UUID v7?
Not universally. ULID has a nicer string; UUID v7 has a formal standard and native support.
Can I store a ULID in a UUID column?
Yes, by converting its 128 bits to UUID format. The result won't have UUID version bits unless your library sets them.
Are ULIDs case-sensitive?
No. Crockford Base32 is case-insensitive; uppercase is the canonical form.
Do both sort correctly as strings?
Yes, both sort by timestamp when compared as text in their canonical forms.
Summary
Both are 128-bit, millisecond-timestamped, sortable IDs. UUID v7 wins on standards and native support; ULID wins on compact, readable strings. Pick based on your storage and interoperability needs.
Related tools
Sources
- RFC 9562 – Universally Unique IDentifiers (UUIDs) – IETF (opens in a new tab)
- ULID specification – ulid/spec on GitHub (opens in a new tab)
Related articles
- What Is UUID v7?The layout of a version 7 UUID, how its timestamp makes IDs sortable, and the limits of that ordering.
- UUID v4 vs UUID v7Random vs time-ordered: index performance, privacy, uniqueness and support compared, with clear recommendations.
- Generate UUID v7Working UUID v7 examples for popular languages and databases, and what to look for in a v7 library.