UUID Version Guide

What is a UUID?

A UUID (Universally Unique Identifier) is a 128-bit number used to uniquely identify objects in software systems. Standardized in RFC 4122, it is formatted as 32 hexadecimal digits in five hyphen-separated groups: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.

UUIDs are designed to be generated without a central authority. Any system can generate a UUID at any time and be confident it will not collide with UUIDs generated by other systems. This property makes them invaluable as database primary keys, request trace IDs, file names, and entity identifiers in distributed architectures.

There are several versions, each with different trade-offs. Version 4 (random) is the most widely used. Version 7 (time-sortable) is rapidly gaining adoption because its chronological ordering makes it much more efficient for database indexing than random UUIDs.

UUID Format

A UUID is a 128-bit identifier displayed as 32 hexadecimal characters in 5 groups:

text
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
  ^        ^    ^    ^    ^
  8 chars  4    4    4    12 chars

M = version (1, 4, 5, 7, ...)
N = variant (8, 9, a, b = RFC 4122)

UUID Versions Compared

VersionAlgorithmSortableUnique GuaranteeBest For
v1Time + MAC addressYes (nanosecond)Yes (per machine)Legacy systems, time-ordered logs
v4Cryptographic randomNoProbabilistic (very high)General purpose IDs
v5SHA-1 hash of name+namespaceNoDeterministicContent-addressed IDs
v7Millisecond timestamp + randomYes (millisecond)YesDatabase primary keys

UUID v4 — Random

javascript
// Node.js
import { randomUUID } from 'crypto';
const id = randomUUID();
// → "f47ac10b-58cc-4372-a567-0e02b2c3d479"

// Browser
const id = crypto.randomUUID();

// Python
import uuid
id = str(uuid.uuid4())

// Go
import "github.com/google/uuid"
id := uuid.New().String()

// Java
String id = UUID.randomUUID().toString();

UUID v7 — Time-Sortable (Recommended for DBs)

text
v7 structure:
┌────────────────────────────────────────────────────────────┐
│ unix_ts_ms (48 bits) │ ver (4) │ rand_a (12) │ var │ rand_b │
└────────────────────────────────────────────────────────────┘

Example: 018e0f1a-7b00-7xxx-8xxx-xxxxxxxxxxxx
         ^^^^^^^^^^^^^^^^ ← timestamp prefix (sortable!)

UUID v7 is PostgreSQL 17+, MariaDB 10.10+, and MySQL 8.0+ compatible. It improves B-tree index performance by avoiding random page splits.

UUID v5 — Name-Based (Deterministic)

javascript
// v5 generates the same UUID for the same input every time
// Useful for: content-addressed IDs, deduplication

import { v5 } from 'uuid';
const NAMESPACE = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; // DNS namespace

const id1 = v5('example.com', NAMESPACE);
const id2 = v5('example.com', NAMESPACE);
console.log(id1 === id2); // true — deterministic!

Database Recommendations

DatabaseRecommended TypeColumn TypeNotes
PostgreSQLUUID v7UUIDNative uuid type, gen_random_uuid() for v4
MySQL / MariaDBUUID v7CHAR(36) or BINARY(16)BINARY(16) is more efficient
SQLiteUUID v4 or v7TEXTNo native UUID type
MongoDBObjectId (12 bytes)ObjectIdObjectId is already time-sortable
DynamoDBUUID v4String (S)No UUID type — store as string

Frequently Asked Questions

UUID v7 for database primary keys (sortable, index-friendly). UUID v4 for everything else (session tokens, request IDs, filenames).

UUID v1 leaks your MAC address and creation timestamp, which can be a privacy concern. Use UUID v7 instead — it's time-sortable without revealing MAC addresses.

UUID v3 and v5 use a namespace (itself a UUID) to scope uniqueness. The RFC defines standard namespaces: DNS, URL, OID, and X500. You can also define your own.

For v4, the probability of collision between two random UUIDs is 1 in 2^122. Generating 1 billion UUIDs per second for 86 years would give ~50% chance of one collision.

BINARY(16) is 2.25× more storage-efficient than CHAR(36) and faster to index. Convert with UUID_TO_BIN() / BIN_TO_UUID() in MySQL 8, or ::uuid in PostgreSQL.

Related Tools