UUIDs Explained: v1 vs v4 vs v5 and When to Use Each

|12 min read

If you've ever needed a unique identifier that works across distributed systems without a central authority, you've likely reached for a UUID. Universally Unique Identifiers are 128-bit labels standardized by RFC 4122 and used everywhere from database primary keys to API request tracing. But not all UUIDs are created equal. Let's break down every version and when each one shines.

UUID Format Breakdown

A UUID is a 128-bit value rendered as 32 hexadecimal digits in the pattern 8-4-4-4-12:

550e8400-e29b-41d4-a716-446655440000
^^^^^^^^ ^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^
time-low mid hi+v clk node (48 bits)

The version is encoded in the high nibble of the 7th byte (the "hi" field), and the variant in the top bits of the 9th byte. This means you can always identify a UUID's version by looking at the first digit of the third group — a 4 in 41d4 tells you it's a v4 UUID.

Version 1: Timestamp + MAC Address

UUID v1 combines the current timestamp (100-nanosecond intervals since October 15, 1582) with the node's MAC address. This guarantees uniqueness across machines and time without any coordination.

Pros:

  • Naturally sortable by creation time
  • No random number generator needed
  • Extremely low collision probability

Cons:

  • Privacy risk: leaks the machine's MAC address
  • Timestamp reveals when the ID was created
  • Not suitable for security-sensitive contexts

Because of the privacy implications, v1 UUIDs have fallen out of favor in public-facing APIs. If you need timestamp-based ordering, consider v7 instead.

Version 3: MD5 Namespace-Based (Deterministic)

UUID v3 generates a deterministic UUID by hashing a namespace UUID and a name with MD5. Given the same namespace and name, you always get the same UUID. This is useful for generating consistent identifiers from known inputs — for example, turning a URL into a UUID that's always the same for that URL.

Because MD5 is considered cryptographically broken, v3 has been superseded by v5 for new applications. Use v5 unless you need backward compatibility with existing v3 UUIDs.

Version 4: Random (The Most Common)

UUID v4 fills 122 of the 128 bits with cryptographically secure random data (the remaining 6 bits encode the version and variant). This is by far the most widely used UUID version today.

// Available in all modern runtimes
const id = crypto.randomUUID();
// "f47ac10b-58cc-4372-a567-0e02b2c3d479"

With 2122 possible values (approximately 5.3 × 1036), the probability of a collision is astronomically low. You'd need to generate about 2.7 quintillion UUIDs to have a 50% chance of a single collision. For all practical purposes, v4 UUIDs are unique.

Version 5: SHA-1 Namespace-Based (Preferred Over v3)

UUID v5 works exactly like v3 but uses SHA-1 instead of MD5. It's the recommended choice for deterministic UUID generation. The standard defines several well-known namespaces:

  • 6ba7b810-9dad-11d1-80b4-00c04fd430c8 — DNS namespace
  • 6ba7b811-9dad-11d1-80b4-00c04fd430c8 — URL namespace
  • 6ba7b812-9dad-11d1-80b4-00c04fd430c8 — OID namespace
  • 6ba7b814-9dad-11d1-80b4-00c04fd430c8 — X.500 DN namespace

Version 7: Unix Timestamp-Based (Sortable, New Standard)

UUID v7 is defined in the new RFC 9562 (superseding the draft that updated RFC 4122). It encodes a Unix timestamp in milliseconds in the first 48 bits, followed by random data. This gives you the best of both worlds:

  • Chronologically sortable — new IDs always sort after older ones
  • No privacy leak — no MAC address or hardware info
  • Database-friendly — sequential inserts reduce B-tree page splits

If you're starting a new project today and need sortable unique IDs, v7 is the strongest recommendation.

UUID Version Comparison

VersionSourceDeterministicSortablePrivacy
v1Timestamp + MACNoYesLeaks MAC
v3MD5(namespace + name)YesNoSafe
v4RandomNoNoSafe
v5SHA-1(namespace + name)YesNoSafe
v7Unix timestamp + randomNoYesSafe

UUID vs Alternatives

UUIDs aren't the only game in town. Here's how they compare to modern alternatives:

FormatSizeSortableFormatBest For
UUID v4128-bitNoHex + dashesGeneral purpose
UUID v7128-bitYesHex + dashesDB primary keys
ULID128-bitYesCrockford Base32Sortable, URL-safe
nanoidConfigurableNoURL-safe alphabetShort IDs, client-side
CUID2VariableNoAlphanumericHorizontal scaling
Snowflake64-bitYesIntegerHigh-throughput systems

ULID is often the best drop-in replacement for UUIDs when you need sortability and URL-safety. nanoid is ideal when you need shorter IDs (e.g., 21 characters) and don't need timestamp ordering. Snowflake IDs (used by Twitter/Discord) are 64-bit integers, making them extremely efficient for high-throughput systems but requiring a central coordinator to assign worker IDs.

Database Performance Considerations

How you store UUIDs has a significant impact on database performance:

Indexing

Random UUIDs (v4) cause random B-tree page splits on insert. This fragments the index and increases I/O. Sequential UUIDs (v1, v7) or ULIDs always insert at the end of the index, maintaining locality and reducing page splits by up to 10x.

Storage

Always store UUIDs as BINARY(16) or your database's native UUID type — never as VARCHAR(36). The string representation is 36 bytes; the binary form is 16 bytes. That's a 56% reduction in index size, which matters at scale.

Clustering

If your table uses a UUID as the clustered primary key (as in InnoDB), random v4 UUIDs force the physical row order to be random, destroying sequential read performance. Use v7 or ULID for clustered keys, or use an auto-increment surrogate key with the UUID as a secondary unique index.

When to Use Sequential vs Random IDs

Use Sequential (v7/ULID)

  • Database primary keys (better write performance)
  • Event logs and audit trails (natural ordering)
  • Time-series data
  • Systems where insert performance is critical
  • When you need to sort by creation time without an extra column

Use Random (v4)

  • Public-facing IDs where creation time must not leak
  • Security tokens and session identifiers
  • Distributed systems with no timestamp coordination
  • When you need to prevent enumeration attacks
  • Idempotency keys generated client-side

Best Practices for UUID Usage

  1. Use v7 for new database primary keys. It gives you sortability, privacy, and better index performance than v4.
  2. Use v4 for security-sensitive tokens. The randomness makes them unpredictable and resistant to enumeration.
  3. Use v5 for deterministic mapping. When you need the same input to always produce the same UUID.
  4. Store as binary, display as string. Use your database's native UUID type or BINARY(16) for storage.
  5. Always lowercase in APIs. UUIDs are case-insensitive, but lowercase is the canonical form per RFC 9562.
  6. Validate on input. Use a regex or library to validate UUID format at API boundaries.
  7. Don't use UUIDs as the sole security mechanism. Even v4 UUIDs should be combined with proper authorization checks.
  8. Consider your ID size budget. If 128 bits is too large for your use case, nanoid at 21 characters or Snowflake at 64 bits may be better fits.

Generate UUIDs Instantly

Try our free UUID generator — supports v1, v4, v5, and v7 with bulk generation and formatting options.

Try it in DevPop →