Home / Guides / UUID Versions Compared
UUID v4 vs v5 vs v7 vs ULID vs NanoID
Five different ways to generate a unique identifier, each solving a different problem. Here's what actually distinguishes them and which one fits your situation.
| Format | Random or deterministic? | Sortable by time? | Length | Best for |
|---|---|---|---|---|
| UUID v4 | Random | No | 36 chars (32 hex + hyphens) | General-purpose unique IDs, the safe default |
| UUID v5 | Deterministic (namespace + name) | No | 36 chars | The same input must always produce the same ID, e.g. deduplication |
| UUID v7 | Random, with embedded timestamp | Yes | 36 chars | Database primary keys, better index locality than v4 |
| ULID | Random, with embedded timestamp | Yes | 26 chars, Base32 | Same use case as v7, outside the UUID format if you don't need RFC compliance |
| NanoID | Random | No | 21 chars by default, customizable | URL-friendly short IDs where 36 characters is overkill |
UUID v4: the default choice
Fully random, defined in the original RFC 4122. If you don't have a specific reason to pick something else, this is it. It's what most libraries generate by default, what most databases and APIs expect, and what crypto.randomUUID() produces natively in every modern browser and Node.js.
UUID v5: when you need the same input to always produce the same ID
v5 hashes a namespace UUID and a name together (via SHA-1, per RFC 4122 §4.3) to produce a deterministic result: the same namespace and name always yield the same UUID. Useful for deduplication (generating a stable ID from a URL or email address, for example) where you want to check for an existing record without a database round-trip first.
UUID v7: the modern choice for database keys
v7 embeds a 48-bit millisecond timestamp in the most significant bits (RFC 9562 §5.7), so IDs sort chronologically while remaining globally unique. Random v4 UUIDs scatter inserts across a database's B-tree index, hurting write performance and cache locality at scale; v7's time-ordering keeps new rows physically near each other, which is why it's increasingly the recommended choice for primary keys over v4.
ULID: the same idea as v7, outside the UUID format
ULID solves the same time-ordering problem as UUID v7 but predates it and uses a different encoding (Base32, 26 characters, case-insensitive) rather than the standard UUID hex-with-hyphens format. If you specifically need RFC-compliant UUIDs (for a column type that enforces the format, for instance), use v7. If you don't have that constraint, ULID's shorter, more compact representation is a reasonable alternative.
NanoID: when 36 characters is too many
NanoID is purely about being short and URL-friendly: 21 characters by default (customizable), no embedded structure, no timestamp. It's a reasonable choice for things like short URL slugs or public-facing IDs where a full UUID would be needlessly long, but it doesn't solve the database-sorting problem v7 and ULID do.
Quick decision guide
- Not sure? Use v4.
- Same input must always produce the same ID? Use v5.
- It's a database primary key and you care about insert performance at scale? Use v7 (or ULID if you don't need strict UUID formatting).
- You need something short for a URL? Use NanoID.
Generate any of these on the UUID generator. v4, v5, and v7 are built in now, with ULID and NanoID planned.
- IETF RFC 9562, Universally Unique IDentifiers (UUIDs), defines v6, v7, v8 and supersedes RFC 4122
- IETF RFC 4122, A Universally Unique IDentifier (UUID) URN Namespace, original v1-v5 specification