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.

FormatRandom or deterministic?Sortable by time?LengthBest for
UUID v4RandomNo36 chars (32 hex + hyphens)General-purpose unique IDs, the safe default
UUID v5Deterministic (namespace + name)No36 charsThe same input must always produce the same ID, e.g. deduplication
UUID v7Random, with embedded timestampYes36 charsDatabase primary keys, better index locality than v4
ULIDRandom, with embedded timestampYes26 chars, Base32Same use case as v7, outside the UUID format if you don't need RFC compliance
NanoIDRandomNo21 chars by default, customizableURL-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

Generate any of these on the UUID generator. v4, v5, and v7 are built in now, with ULID and NanoID planned.

Sources: