← Back to all articles

Which UUID Version? v1, v4, v7 and When Not to Use One

IdentifiersPitfalls

Comparing the common versions

VersionCompositionTraitsUse for
v1Timestamp + node (MAC)Roughly ordered but leaks time and device infoInternal legacy systems needing ordering
v4122 random bitsMost common, unorderedGeneral-purpose unique IDs
v7Timestamp prefix + randomSortable by time, index-friendlyDatabase primary keys, log IDs

How likely is a collision

For v4 you would need roughly 2.7×10¹⁸ UUIDs to reach a 50% chance of a single collision. At realistic scale, duplicates are not the problem — disorder is.

The primary-key performance trap

Random UUIDs scatter B+ tree inserts, causing page splits and write amplification; as data grows, insert throughput and cache hit rate both drop. Keep IDs time-local instead: use v7 / ULID, or an auto-increment or snowflake ID. Systems already full of v4 keys can keep the UUID as the public identifier and add an internal ordered key.

Three cases where UUIDs are the wrong tool

  1. Short, speakable identifiers: invite codes and short links need something shorter (a Base62 random string);
  2. Human-recognisable references: order numbers read better with semantic rules;
  3. Security tokens: see below.

Common questions

Can a UUID be a password or a token? No. A v4 UUID offers 122 random bits and carries no expiry, scope or revocation semantics; use a purpose-built token (256 random bits plus server-side validation). Does a UUID leak information? v1 leaks creation time and the device MAC; v7 leaks the creation time (usually acceptable); v4 leaks no structure at all.

Choosing an ID scheme

OptionOrderingSizeUse for
Auto-incrementNaturally orderedSmallestSingle database, internal systems
Snowflake IDTime-ordered64-bit integerDistributed systems needing compact IDs
UUID v4Unordered36 charactersGeneral unique IDs, public identifiers
UUID v7 / ULIDTime-ordered36 / 26 charactersPrimary keys, log correlation

Generating and using them well

  1. Use the platform or a standard library (crypto.randomUUID(), language-specific uuid packages) — never build one from Math.random(), which is not cryptographically secure;
  2. Store 16 raw bytes or the 32-character hyphenless form: less space and faster comparisons than the canonical 36-character string;
  3. If you query by time, keep the ordering inside the ID (v7 / ULID); otherwise add an indexed created_at column;
  4. Assess leakage before exposing IDs: v1 carries time and MAC, v7 carries creation time, v4 carries no structure.

Real-world cases: three lessons from primary-key migrations

  1. "Writes got slower after switching to UUIDs": random v4 keys scatter B+ tree inserts and cause page splits. Fix: use v7/ULID, or keep an auto-increment key and expose the UUID only publicly.
  2. "Public IDs let people infer a pattern": v1 embeds time and MAC, potentially exposing creation time and device. Fix: expose v4 only, or at least never expose v1.
  3. "Logs can't be sorted by time because of the UUID": v4 is unordered. Fix: use v7/ULID for log IDs — time-ordered and easy to paginate.

FAQ

Can a UUID v4 collide? Extremely unlikely (about 2.7×10¹⁸ to reach a 50% chance), but add a unique constraint as a safety net. Can a UUID be a session token? Not advisable — it has no expiry, scope or revocation; use a 256-bit random string with server-side validation. Is dropping hyphens worth it? Smaller and faster to compare, slightly less readable; storage often uses 16 raw bytes. ULID or v7? Both are time-sortable; ULID is shorter (26 chars, Crockford Base32), v7 is standard UUID format (36 chars) — pick by ecosystem habit.

Try it: UUID generator

Version overview

  • v1: timestamp plus MAC address — sortable but potentially leaking machine details;
  • v3 / v5: deterministic hashes of a namespace and name (MD5 and SHA-1 respectively) — same input, same UUID, ideal as stable mapping keys;
  • v4: 122 random bits, best privacy, but unordered and therefore random index writes;
  • v6 / v7: newer standards putting time first for sortability; v7 aligns with Unix milliseconds and suits primary keys;
  • Rule of thumb: v7/ULID for ordering, v5 for deterministic mapping, v4 when you only need uniqueness.

Migration and coexistence

Moving from auto-increment to UUID primary keys is expensive (index rebuilds, foreign key changes). The safer path is to keep the original key, add a public identifier column, backfill history, and only reconsider the physical key once every consumer has switched. Half-finished migrations leave data that does not reconcile.