UUID v1 vs v4 vs v5 vs v7: Which Version Should You Use?

What each UUID version is built from, why v4 is the safe default, when name-based v5 helps, and why time-ordered v7 is becoming the choice for database keys.

· 4 min read

A UUID is a 128-bit identifier written as 32 hex digits in five groups, like f47ac10b-58cc-4372-a567-0e02b2c3d479. Different versions build those 128 bits in different ways, and the version you pick affects privacy, database performance and whether two systems can produce the same ID independently. Here's how they compare.

How to tell a UUID's version

The version is the first digit of the third group:

f47ac10b-58cc-4372-a567-0e02b2c3d479
               ^
               version 4

The first digit of the fourth group (a here) holds the variant. For standard UUIDs it's always 8, 9, a or b.

The versions at a glance

VersionBuilt fromSortable by timeMain use
v1Timestamp + MAC addressNot directlyLegacy systems
v3MD5 hash of a namespace + nameNoLegacy name-based IDs
v4Random bitsNoGeneral-purpose default
v5SHA-1 hash of a namespace + nameNoSame input should always give the same ID
v7Unix timestamp in milliseconds + random bitsYesDatabase primary keys, logs, events

Versions 6 and 8 also exist. v6 reorders v1's fields so it sorts by time, and v8 is a free-form format for custom schemes. Both are uncommon.

v4: random, and the safe default

A v4 UUID is 122 random bits plus the version and variant markers. That's about 5.3 × 10³⁶ possible values. You could generate a billion per second for decades before a collision became likely, provided the random number generator is good.

Every modern platform can make one:

crypto.randomUUID(); // browsers and Node.js
import uuid
uuid.uuid4()

Use v4 when you need a unique ID and nothing else matters about it. It reveals nothing about when or where it was created. You can generate single or bulk v4 UUIDs with the UUID generator.

v1: time and machine

v1 combines a 60-bit timestamp with a node ID that's usually the network card's MAC address. That makes it unique without randomness, but it leaks the machine and the moment the ID was created, which you may not want in a public URL. Its timestamp fields are also stored in an order that doesn't sort chronologically. Unless you're matching an existing system, choose v4 or v7 instead.

v3 and v5: same input, same UUID

Name-based UUIDs hash a namespace UUID together with a name. The same namespace and name always produce the same UUID, on any machine:

import uuid
uuid.uuid5(uuid.NAMESPACE_URL, "https://tooldock.dev/tools")
# Same result every time, everywhere

That's useful when several systems need to agree on an ID without talking to each other, or when you want imports to be repeatable. For example, you can derive a stable ID from an email address or a file path.

v5 uses SHA-1 and v3 uses MD5. Prefer v5. Neither is meant to be secret: if someone can guess the name, they can recompute the UUID.

v7: time-ordered, and better for databases

v7, standardized in RFC 9562 in 2024, puts a 48-bit Unix timestamp in milliseconds at the front and fills the rest with random bits. UUIDs created later sort after ones created earlier.

That matters for database primary keys. Random v4 keys land in random places in a B-tree index, so every insert touches a different page. On large tables that causes page splits, a bloated index and poor cache use. v7 keys arrive in roughly increasing order, so inserts append near the end of the index, much like an auto-increment integer, while keeping the benefits of a UUID:

  • IDs can be generated by any service without asking the database.
  • They don't reveal how many rows you have, as sequential integers do.
  • They merge cleanly across databases and shards.

The trade-off is that a v7 UUID reveals roughly when it was created. That's usually fine for internal keys, but think about it before exposing them.

Support is still spreading. PostgreSQL 18 added a built-in uuidv7() function, Python 3.14 added uuid.uuid7(), and the uuid package for Node.js provides v7(). ToolDock's generator currently makes v1, v3, v4 and v5 UUIDs, plus the nil UUID.

UUID vs GUID

GUID is Microsoft's name for the same thing. A GUID from .NET's Guid.NewGuid() is a v4 UUID. The only practical difference is presentation: Windows tools often show GUIDs in uppercase and sometimes wrap them in braces, like {F47AC10B-58CC-4372-A567-0E02B2C3D479}.

Storing UUIDs

  • PostgreSQL: use the native uuid type. It stores 16 bytes and validates input.
  • MySQL: store as BINARY(16) rather than CHAR(36). The text form takes more than twice the space and makes indexes slower. UUID_TO_BIN() and BIN_TO_UUID() convert between the two.
  • Everywhere: compare UUIDs case-insensitively, or normalize them to lowercase when you store them.

Which one should you use?

  • No special requirements: v4.
  • Database primary keys, logs, events: v7, if your stack supports it.
  • The same input must always give the same ID: v5.
  • An existing system expects v1: v1. Otherwise avoid it.

Need some UUIDs now? Generate them in bulk with the UUID generator.