**By Dev Tools Weekly** | createuuid.com
When to use v1 vs v4 vs v5 vs v7 — with code examples.
UUID Format
xxxxxxxx-xxxx-Vxxx-Yxxx-xxxxxxxxxxxx
│ │
│ └── Variant (8, 9, a, or b = RFC 4122)
└─────── Version digit (1-8)
Total: 128 bits = 32 hex characters + 4 hyphens = 36 characters
Example: 550e8400-e29b-41d4-a716-446655440000
- Version:
4(position 13) - Variant:
a(position 17, starts with binary10xx)
Version Comparison
| Version | Based On | Sortable? | Unique Without Coordination? | Use When |
|---|---|---|---|---|
| **v1** | Timestamp + MAC | ✅ (roughly) | ✅ | Need time-ordering, don't mind leaking MAC |
| **v3** | MD5 hash of name | ❌ | ❌ (deterministic) | Consistent ID from a name (legacy) |
| **v4** | Random | ❌ | ✅ | Default choice — random unique IDs |
| **v5** | SHA-1 hash of name | ❌ | ❌ (deterministic) | Consistent ID from a name (preferred over v3) |
| **v6** | Reordered v1 | ✅ | ✅ | Time-sortable v1 replacement (new) |
| **v7** | Unix timestamp + random | ✅ | ✅ | **Best for databases** — sortable, no MAC leak |
| **v8** | Custom | varies | varies | Custom/experimental |
Deep Dive: Each Version
Version 1 — Timestamp + MAC Address
Structure: time_low - time_mid - time_hi_version - clock_seq - node(MAC)
Bits: 32 16 16 16 48
- **Timestamp:** 60-bit count of 100ns intervals since Oct 15, 1582
- **Clock sequence:** 14 bits, prevents duplicates if clock resets
- **Node:** 48-bit MAC address of the generating machine
⚠️ Privacy concern: Embeds the machine's real MAC address. Avoid in public-facing IDs.
✅ Good for: Internal systems where time-ordering matters and you control the infrastructure.
Version 4 — Random
All 122 bits are randomly generated (6 bits reserved for version/variant).
- **Collision probability:** ~50% chance of one duplicate after generating 2.71 × 10¹⁸ UUIDs
- **That's:** 1 billion UUIDs per second for 86 years before a 50% collision chance
- **No coordination needed** — any machine can generate independently
✅ Good for: Almost everything. Default choice for database PKs, API keys, session IDs.
Version 5 — Name-Based (SHA-1)
UUID = SHA-1(namespace_UUID + name)[first 128 bits]
Predefined namespaces:
| Namespace | UUID | Use For |
|---|---|---|
| DNS | 6ba7b810-9dad-11d1-80b4-00c04fd430c8 | Domain names |
| URL | 6ba7b811-9dad-11d1-80b4-00c04fd430c8 | URLs |
| OID | 6ba7b812-9dad-11d1-80b4-00c04fd430c8 | ISO OIDs |
| X.500 | 6ba7b814-9dad-11d1-80b4-00c04fd430c8 | X.500 DNs |
Key property: Same namespace + same name → always the same UUID.
✅ Good for: Deterministic IDs from URLs, emails, domain names. Idempotent operations.
Version 7 — Unix Timestamp + Random (NEW — RFC 9562)
Structure:
┌──────────────────┬────┬──────────────────────────────┐
│ Unix ms (48 bit) │ V │ Random (74 bits) │
└──────────────────┴────┴──────────────────────────────┘
- **Timestamp:** 48-bit Unix millisecond epoch (good until year 10889)
- **Random:** 74 random bits for uniqueness
- **Sortable:** Sorts chronologically when compared as strings or bytes
✅ Best for databases: Natural sort order = better B-tree index performance than random v4. No MAC leak like v1.
UUID vs. Alternatives
| Identifier | Bits | Sortable | Length | Notes |
|---|---|---|---|---|
| UUID v4 | 128 | ❌ | 36 chars | Universal standard |
| UUID v7 | 128 | ✅ | 36 chars | New standard, recommended |
| ULID | 128 | ✅ | 26 chars (Crockford Base32) | Compact, popular in JS |
| Snowflake | 64 | ✅ | ~19 digits | Twitter/Discord. Needs coordinator. |
| KSUID | 160 | ✅ | 27 chars | Segment. Large, very unique. |
| NanoID | configurable | ❌ | 21 chars default | URL-safe, configurable alphabet |
| CUID2 | 128 | ✅ | 24 chars | Collision-resistant, secure |
| ObjectId (Mongo) | 96 | ✅ | 24 hex | Timestamp + machine + counter |
Code Examples
JavaScript / TypeScript
// Native (v4 random)
crypto.randomUUID();
// → "550e8400-e29b-41d4-a716-446655440000"
// UUID v7 (using 'uuid' package)
import { v7 as uuidv7 } from 'uuid';
uuidv7();
// → "01902e1c-0e2d-7000-8a3b-2c1d4e5f6a7b"
Python
import uuid
uuid.uuid4() # Random
uuid.uuid1() # Timestamp + MAC
uuid.uuid5(uuid.NAMESPACE_DNS, "example.com") # Name-based
PostgreSQL
-- Built-in (v4)
SELECT gen_random_uuid();
-- v7 (PostgreSQL 17+)
SELECT uuidv7(); -- or use extension
-- Use as primary key
CREATE TABLE users (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
name TEXT NOT NULL
);
Go
import "github.com/google/uuid"
id := uuid.New() // v4
id := uuid.Must(uuid.NewV7()) // v7
Decision Flowchart
Need a unique ID?
├── Need to be deterministic (same input → same ID)?
│ └── YES → Use v5 (name-based SHA-1)
├── Need time-sortable IDs?
│ ├── For a database PK? → Use v7
│ └── For distributed systems? → Use v7 or ULID
└── Just need random uniqueness?
└── Use v4 (the default)
🛠 Generate UUIDs instantly: createuuid.com
📧 More cheat sheets: Dev Tools Weekly Newsletter