UUID v1 vs v4 vs v5 vs v7 — Differences Explained (and Which to Pick)
All UUIDs look the same — 36 characters of hex in the familiar 8-4-4-4-12 pattern — but the version digit hides very different generation strategies. Some encode a timestamp and your network card's MAC address, some are pure randomness, some are deterministic hashes, and the newest one is engineered specifically to keep database indexes fast. This guide tours the four versions you will actually meet (v1, v4, v5, and v7), with a comparison table and clear advice on when to pick each.
UUID v1 — Timestamp + MAC Address (the Original)
Version 1 builds a UUID from a 60-bit timestamp (100-nanosecond intervals since 15 October 1582 — the Gregorian calendar epoch), a clock sequence to handle clock resets, and a 48-bit node identifier that was traditionally the machine's MAC address.
c232ab00-9414-11ec-b3c8-9f6bdeced846
^^^^^^^^ ^^^^ ^^^ ^^^^^^^^^^^^
time-low time time-high node (often the MAC address)
(version 1)Uniqueness is excellent — time plus a unique hardware address rarely collides — but v1 has two serious problems:
- Privacy leak — anyone holding the UUID can extract the creation time and the MAC address of the generating machine. The author of the 1999 Melissa virus was traced partly through a GUID embedding his MAC address.
- Awkward sort order — the timestamp bytes are stored low-order first, so v1 UUIDs do not sort chronologically as strings, wasting the one benefit of embedding time.
Modern libraries substitute random node IDs to hide the MAC, but at that point v7 does everything v1 does, better. Treat v1 as legacy.
UUID v4 — Pure Randomness (the Workhorse)
Version 4 fills 122 bits with output from a cryptographically secure random number generator; the other 6 bits mark the version and variant. That gives about 5.3 × 10^36 possible values — enough that collisions are a theoretical curiosity, not an engineering concern.
// One line in any modern browser or Node.js 19+ crypto.randomUUID(); // '7f9c24e8-3b12-4c8f-9a6d-e51fca2aa07f' // ^ version 4
v4 is the default almost everywhere because it is simple, unguessable, and leaks nothing — no time, no hardware, no counter. Its one weakness shows up at database scale: consecutive v4 values land in random spots across a B-tree index, causing page splits and cache misses on insert-heavy tables. If your IDs will be a primary key on a large table, keep reading.
UUID v5 — Deterministic, Name-Based (the Odd One Out)
Version 5 is fundamentally different: it is not random at all. You give it a namespace UUID and a name (any string), it hashes them with SHA-1, and it packs 122 bits of the digest into UUID form. The same namespace + name always produces the same UUID, on any machine, in any language:
import uuid
# Same inputs -> same UUID, every time, everywhere
uuid.uuid5(uuid.NAMESPACE_DNS, 'dev-brains-ai.com')
# UUID('6ed258d2-8bfd-5b3a-a4b8-2c1c2b0f4f52') (version 5)Use v5 when you need reproducible IDs: mapping external keys (emails, URLs, product codes) to stable UUIDs, idempotent imports where re-running must not create duplicates, or generating the same ID independently in two services. Note that SHA-1 is fine here — v5 is about determinism, not cryptographic secrecy — but anyone who knows the namespace and name can compute the UUID, so never treat a v5 UUID as a secret.
UUID v7 — Time-Ordered Random (the Modern Default)
Version 7, standardised in RFC 9562 (2024), fixes v4's database problem while keeping its safety. The first 48 bits are a Unix timestamp in milliseconds; the remaining 74 bits are random:
018f4e2a-5b1c-7d3e-9f4a-1c2b3d4e5f6a \_____________/ ^ 48-bit Unix ms version 7, then 74 random bits Generated later -> sorts later (as string AND as bytes)
- Index-friendly — new rows always land at the right edge of the B-tree, like auto-increment IDs, so inserts stay fast and indexes stay compact.
- Still unguessable — 74 random bits per millisecond is far beyond brute-force range.
- Roughly sortable by creation time — handy for pagination and debugging, without a separate created_at sort in many cases.
- Mild trade-off — it does reveal creation time, which is usually harmless but worth knowing.
PostgreSQL 18 ships uuidv7() natively, and mature libraries exist for JavaScript, Python, Java, Go, and Rust. For new systems where UUIDs are primary keys, v7 is the modern default.
Comparison Table and How to Choose
Version | Built from | Sortable | Deterministic | Leaks info | Verdict --------|-----------------------|----------|---------------|-----------------|------------------ v1 | timestamp + MAC | poorly | no | time + MAC addr | legacy, avoid v4 | 122 random bits | no | no | nothing | fine everywhere v5 | SHA-1(namespace+name) | no | YES | nothing* | reproducible IDs v7 | unix ms + 74 random | YES | no | creation time | modern default * computable by anyone who knows the inputs
- Database primary keys, event IDs, anything insert-heavy → v7
- Session tokens, API keys' IDs, anywhere time leakage bothers you → v4
- Same input must always yield the same ID → v5
- Maintaining a system that already uses v1 → keep it working, migrate to v7 when convenient
Want to compare outputs side by side? The free UUID generator lets you generate UUIDs in your browser and inspect the version digit yourself.
Frequently Asked Questions
For most new applications, use UUID v7 if your libraries and database support it — it is random enough to be unguessable but time-ordered, so database indexes stay fast. Use v4 when you just need a random ID and insert order does not matter, and v5 when you need the same input to always produce the same UUID.
A classic UUID v1 embeds the generating machine's MAC address and a precise timestamp. Anyone who sees the UUID can extract when it was created and potentially which network card created it. The Melissa virus author was famously traced partly via a GUID containing his MAC address.
UUID v4 is 122 bits of pure randomness, so consecutive IDs are scattered across the entire value space. UUID v7 puts a 48-bit Unix millisecond timestamp in front of 74 random bits, so IDs generated later sort later. That ordering keeps B-tree database indexes compact and makes inserts significantly faster at scale.