Comparison
UUID v7 vs ULID
Both are 128 bits and both start with a Unix millisecond timestamp. They are not the same identifier: ULID has no version or variant, and its usual text form is Crockford base32.
| UUID v7 | ULID | |
|---|---|---|
| Width | 128 bits | 128 bits |
| Timestamp | 48-bit Unix milliseconds | 48-bit Unix milliseconds |
| After the timestamp | 4 version bits, 12 rand_a bits, 2 variant bits, 62 rand_b bits | 80 random bits |
| Usual text | 36 characters, hexadecimal and hyphens | 26 characters, Crockford base32 |
| Version field | 7 | None |
| Monotonic option | Allowed by RFC 9562; this site uses random bits | The ULID spec describes incrementing the random part in the same millisecond |
| Native UUID type | Yes, when the variant and version are set | No. It is a different identifier |
Choose UUID v7 when the column, the API, or the parser already expects a UUID. Choose ULID when the surrounding system already uses its 26-character text. Converting one into the other by copying bytes does not change the spec that produced those bytes.
Questions
Are they the same 128 bits?
Both are 128 bits and both start with a 48-bit Unix millisecond timestamp. ULID then has 80 random bits. UUID v7 uses 4 version bits and 2 variant bits, leaving 74 bits for the random portion defined by RFC 9562.
Can I store a ULID in a UUID column?
A ULID is not a UUID. Some code writes the 16 ULID bytes into a uuid column, but the version nibble is then whatever those bits happen to be. That value is not a UUID v7.
Which text form sorts?
A ULID's 26-character Crockford base32 text sorts by time. A canonical UUID v7 hex string also sorts by the millisecond timestamp because the timestamp is first and the hyphens sit in fixed places.