Skip to content

UUID vs ULID vs Nano ID: Size, Sorting and Collisions

Last updated Published by Hyperdusk Ltd

The short answer

A UUID is a 128-bit identifier standardised in RFC 9562 and written as 36 characters. A ULID is also 128 bits, with a millisecond timestamp first, written as 26 characters. A Nano ID is a random string, 21 characters by default, carrying 126 random bits. UUID v7 and ULID sort by creation time; UUID v4 and Nano ID do not.

Generate UUID v4 and v7 values online →

Key differences

UUID v4, UUID v7, ULID and Nano ID side by side
UUID v4UUID v7ULIDNano ID
Specified byRFC 9562RFC 9562The ulid/spec repositoryThe Nano ID library's README
Size128 bits128 bits128 bits126 bits by default
Text length36362621 by default
AlphabetHex digits and hyphensHex digits and hyphensCrockford base32: no I, L, O or UA-Z, a-z, 0-9, _ and -
Bits per character4456
TimestampNone48-bit Unix ms48-bit Unix msNone
Random bits122Up to 7480126
Sorts by creation timeNoYesYesNo
Case-sensitiveNoNoNoYes

What is a ULID?

ULID stands for Universally Unique Lexicographically Sortable Identifier. Its specification is a README in the ulid/spec repository on GitHub, not a standards document. A ULID is 128 bits: a 48-bit Unix timestamp in milliseconds followed by 80 bits of randomness. The spec says the timestamp will not run out until the year 10889.

It is written as 26 characters of Crockford's base32, which leaves out I, L, O and U to avoid confusion and is case-insensitive. Because the timestamp comes first, ULIDs sort by creation time as plain text. Within the same millisecond the spec says sort order is not guaranteed unless the generator is monotonic, in which case it increments the random part by one for each new ID.

A ULID is the same size as a UUID and its first 48 bits mean the same thing as a UUID v7's. It does not reserve the version and variant bits that RFC 9562 requires, so a ULID stored in a UUID column is not a valid UUID v7.

What is a Nano ID?

Nano ID is a JavaScript library that describes itself as "a tiny, secure, URL-friendly, unique string ID generator". By default it returns 21 characters drawn from a 64-symbol alphabet: A-Z, a-z, 0-9, underscore and hyphen. At 6 bits per character that is 126 random bits, which its README compares with the 122 in a UUID v4.

There is no timestamp and no internal structure, so Nano IDs do not sort by time. Both the length and the alphabet can be changed. The README warns that a shorter ID raises the collision probability and links a calculator for checking a custom size.

Which of them sort by creation time?

UUID v7 and ULID. Both put a 48-bit millisecond timestamp in the most significant bits, so comparing two IDs as text or as bytes compares their creation times first. UUID v4 and Nano ID are random throughout and have no order.

Ordering matters most for database keys. RFC 9562 says that UUIDs which are not time-ordered have poor database index locality, because new values are inserted at random positions in the index. The RFC lists ULID among the earlier time-ordered formats it reviewed when defining v7.

The cost of a leading timestamp is that every ID shows when it was created.

How do the collision odds compare?

For the two random formats, what matters is the total number of IDs ever generated. For the two time-ordered formats, only IDs created in the same millisecond can collide, so what matters is the generation rate.

IDs needed before a collision becomes likely
FormatRandom bitsIDs for a 1-in-a-billion chanceIDs for a 50% chance
UUID v41221.03 × 10^14 in total2.71 × 10^18 in total
Nano ID (21 characters)1264.12 × 10^14 in total1.09 × 10^19 in total
UUID v7746.15 million in one millisecond1.62 × 10^11 in one millisecond
ULID8049.2 million in one millisecond1.29 × 10^12 in one millisecond
Computed with the birthday bound, n ≈ √(2N · ln(1/(1−p))), where N is 2 to the power of the random bits. The UUID v7 row assumes all 74 bits are random. The UUID v4 figure matches the one quoted in the Nano ID README: 103 trillion IDs for a one-in-a-billion chance.

At ordinary generation rates none of the four is a practical risk. The figures only hold with a cryptographically secure random source.

Which is shortest in a URL or a database?

As text, a Nano ID is 21 characters, a ULID is 26 and a UUID is 36. In binary, a UUID and a ULID are both 16 bytes. A Nano ID is a string and is stored as one.

UUIDs have built-in database support: PostgreSQL, for example, has a native uuid column type and functions that generate v4 and v7. ULID and Nano ID come from libraries, so the application generates them and the database sees text or bytes.

A ULID can be read aloud or typed without worrying about case. A Nano ID cannot, because a and A are different characters in its alphabet.

Which should you use?

Use UUID v7 when you want a time-ordered key that follows a published standard and that databases can generate and store natively. Use UUID v4 when the ID should carry no timestamp and you still want a standard format.

Use ULID when you need time ordering in a shorter, case-insensitive string and a library for your language is acceptable. Use Nano ID for short, URL-safe identifiers that are handled as strings and never need to sort, such as share links or client-side keys.

Tools for this

Sources

This page was written from the primary sources below, read on .

  • RFC 9562: Universally Unique IDentifiers (UUIDs)

    IETF. UUID v4 and v7 layouts, text format, the index-locality rationale and the list of earlier formats reviewed.

  • ULID specification

    ulid/spec on GitHub. The 48-bit timestamp and 80-bit randomness layout, Crockford base32 encoding, sorting and monotonicity rules.

  • Nano ID README

    ai/nanoid on GitHub. Default length and alphabet, the 126-bit comparison with UUID v4, and the custom size and alphabet options.

  • PostgreSQL 18: UUID Functions

    PostgreSQL Global Development Group. Native uuidv4() and uuidv7() generation.

Published by Hyperdusk Ltd. Last updated . Figures in computed tables were produced by the method stated under each table.

All guides→