Skip to content

GUID Versions Explained: v1–v7 and Which to Choose

2026-07-09

Tags: Windows · GUID · Guide · QuickGUID


Open any UUID library and you'll see uuid1(), uuid3(), uuid4(), uuid5(), and increasingly uuid7(). The spec defines eight versions. Which one do you actually use?

The short answer is: v4 for almost everything, v7 for database primary keys, v5 when you need the same input to always produce the same GUID. The rest of this article explains why — with byte layouts, real-world reasons each version exists, and a per-language code cheatsheet.

If you're new to GUIDs entirely, start with What Is a GUID? for the basics of structure and uniqueness. This post is the technical companion — it goes deeper on every version.

The GUID/UUID Version Landscape

Each version is a different recipe for filling the same 128 bits. The version nibble (first hex digit of the third segment) tells you which recipe was used.

VersionGeneration sourceSortableTypical use
v1Time + MAC addressYesLegacy systems (privacy risk)
v2DCE SecurityYesRare, specialized
v3MD5 namespace hashNoDeprecated (use v5)
v4RandomNoGeneral default
v5SHA-1 namespace hashNoDeterministic IDs
v6Reordered v1 timeYesDrop-in v1 replacement
v7Millisecond timestampYesDatabase primary keys
v8Vendor-definedCustomSpecialized

Versions v1, v4, v5, and v7 cover 99% of real-world usage. Let's walk through each.

v1: Time and MAC Address

v1 is the original recipe from RFC 4122. It packs three things into 128 bits:

| time_low (32) | time_mid (16) | ver+time_hi (16) | var+clk_seq (16) | node/MAC (48) |
  • 60-bit timestamp — 100-nanosecond intervals since 1582-10-15 (the Gregorian calendar adoption date). The timestamp is split across time_low, time_mid, and time_hi.
  • 14-bit clock sequence — a counter that disambiguates two GUIDs generated within the same clock tick, or when the system clock was set backward.
  • 48-bit node — the network card's MAC address.

The MAC address problem

The node field is a hardware fingerprint. Any v1 GUID you publish carries your machine's MAC address — and unlike an IP address, a MAC address is meant to be globally unique and persistent. This is a real privacy leak.

It's not theoretical. Researchers have shown you can trace documents back to the machine that created them by reading v1 GUIDs embedded in file metadata. Microsoft itself stripped v1 generation out of Office telemetry after this was demonstrated. Modern operating systems also randomize the MAC shown to Wi-Fi networks for the same reason.

Verdict: avoid v1 in new code. It survives in legacy systems, COM interfaces, and some hardware-adjacent tooling — but there's no reason to generate it yourself today.

v2: DCE Security

v2 is the version you will essentially never encounter. It takes the v1 layout (timestamp + MAC) and overlays a POSIX UID/GID — the local user and group identifiers from the DCE (Distributed Computing Environment) security model — so that the UUID can carry access-control information alongside its uniqueness.

v2 exists for DCE/RPC authentication and ACLs in legacy enterprise systems. Unless you maintain software that explicitly speaks DCE Security, you will never generate or consume a v2. It appears here purely so the version list is complete and you won't be left wondering what a "2" in that nibble means if you ever do spot one.

v3: Why It Was Deprecated

v3 is identical to v5 except it uses MD5 instead of SHA-1. MD5 has practical collision attacks — two different inputs can be crafted to produce the same hash. That breaks v3's determinism guarantee in adversarial settings.

RFC 4122 kept v3 for backwards compatibility but v5 superseded it. There is no reason to generate v3 today. If you encounter a v3 in the wild, treat it as legacy.

v4: The Random Default

v4 is what you get from virtually every "generate a GUID" call: [guid]::NewGuid(), Guid.NewGuid(), crypto.randomUUID(), uuid.uuid4(), NEWID(). It fills 122 of the 128 bits with cryptographically strong randomness (the other 6 bits are the version and variant markers).

No timestamp, no MAC, no machine state — pure randomness. That makes v4 safe to expose, trivially parallelizable, and collision-resistant enough for any realistic workload. For the full collision math (and why the viral "1 billion years" claim gets the birthday paradox wrong), see the hub article.

Verdict: this is your default. Pick v4 unless you have a specific reason to pick something else.

v5: Deterministic Namespace IDs

This is the version most developers have heard of but never actually used — and it solves a genuinely useful problem.

v5 lets you derive the same GUID from the same input, every time. Hand it a namespace UUID and a name string, and it returns a deterministic identifier:

python
import uuid

# Same input → same GUID, every run, every machine
dns_guid = uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com')
url_guid = uuid.uuid5(uuid.NAMESPACE_URL, 'https://prunelab.net/blog/guid-explained')

print(dns_guid)  # always  cf14e0a3-... (same value)
print(dns_guid == uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com'))  # True

How it works

Internally, v5 concatenates the namespace UUID bytes with the UTF-8 name bytes, runs SHA-1 over the result, takes the first 16 bytes, then stamps the version (5) and variant bits. The namespace itself is a UUID — NAMESPACE_DNS, NAMESPACE_URL, NAMESPACE_OID, and NAMESPACE_X500 are predefined, but you can use any UUID as the namespace.

When v5 is the right tool

  • Reproducible test fixtures — generate IDs for test data that stay stable across runs, so a failing test points at the same entity every time.
  • URL-derived identifiers — turn a URL into a GUID without a database lookup. Two systems that independently compute uuid5(NAMESPACE_URL, url) for the same URL always agree.
  • Idempotent deduplication — import the same record twice and the GUID collides with itself, so you can detect the duplicate by key alone.

The key contrast with v4: v4 returns a unique value per call (even for identical inputs); v5 returns a stable value for identical inputs. They're not interchangeable.

Verdict: reach for v5 whenever you need a GUID that reproducibly maps from some input string.

v6: The v1 Fix You Probably Don't Need

v6 contains the exact same data as v1 — the same timestamp, clock sequence, and MAC — but reorganizes the timestamp bits so the value sorts naturally in chronological order. In v1 the timestamp is awkwardly split (low, mid, high); in v6 it's stored high-first, so lexical string sorting equals time sorting.

v6 was standardized in RFC 9562 (2024) alongside v7. It exists mainly as a drop-in migration path for systems already wedded to v1's clock-and-MAC model: you keep your existing timestamp logic and just rewrite the bit layout.

For new systems, v7 is almost always the better choice. v7 uses a millisecond timestamp (simpler than v1/v6's 100-ns Gregorian count), doesn't embed a MAC address, and has cleaner random fill. v6 is the answer to "how do I modernize v1 without changing my generation model"; v7 is the answer to "what should I use going forward."

v7: Time-Ordered for Databases

v7 is the most important new addition since v4. It solves a problem v4 creates in databases.

The v4 database problem

When a database uses GUIDs as primary keys, those keys back a B+ tree index. B+ trees stay efficient when inserts are roughly ordered — new values land at the right edge and fill existing pages. Random v4 GUIDs scatter across the entire key space, so every insert hits a random page. On large tables this causes constant page splits, index fragmentation, cache thrash, and write amplification. The fix in SQL Server (NEWSEQUENTIALID()) is a proprietary, non-portable hack that leaks sequencing.

v7's layout

| unix_ts_ms (48) | ver (4) | rand_a (12) | var (2) | rand_b (62) |
  • 48-bit millisecond Unix timestamp — leading field, so values increase over time.
  • 4-bit version — set to 7.
  • 12-bit rand_a — random, or optionally a monotonic counter to order within the same millisecond.
  • 2-bit variant — the standard RFC 9562 marker.
  • 62-bit rand_b — random.

Because the timestamp leads, v7 GUIDs generated in sequence are naturally ordered: index inserts cluster at the right edge, pages fill cleanly, and the B+ tree behaves like it does with an auto-increment integer — while still being globally unique with no central coordinator.

When v7 is NOT worth it

  • In-memory stores (Redis, memcached) — no B+ tree, no fragmentation cost. v4 is fine.
  • Small tables — the difference between v4 and v7 is invisible below millions of rows.
  • Non-key columns — if the GUID is just a stored attribute and not an index key, ordering is irrelevant.
  • GUIDs that must be opaque — v7 leaks the generation millisecond, which may be undesirable in security-sensitive contexts.

Verdict: if a GUID is a clustered primary key on a real database, use v7. Otherwise v4.

v8: Vendor-Defined

v8 is the escape hatch: RFC 9562 lets the vendor define its own bit layout, as long as the version nibble reads 8 and the variant bits are correct. Everything else — timestamp width, randomness source, encoding — is up to the implementer.

You'll only see v8 in systems that designed a custom UUID scheme for a specific reason (for example, baking a shard ID or node ID into the UUID for routing). If you're not building such a system, v8 is irrelevant; and if you are, the rules are whatever your own scheme defines, not anything in this article.

Which Version Should You Actually Use?

A decision guide:

  • "Generating IDs for general use?"v4. This is the answer 90% of the time.
  • "Database primary key, or need time ordering?"v7. Especially for clustered indexes on large tables.
  • "Need the same GUID for the same input every time?"v5. Deterministic mapping from a string.
  • "Working with a legacy system that expects v1?"v1 (keep compatibility), but plan a migration to v7.
  • "Someone told me to use v3?" → Don't. Use v5 instead (MD5 in v3 is broken).
  • "I want the newest thing." → That's not a reason. v7 is new and solves a real problem (DB ordering); v6 is new and mostly a v1 migration aid. Pick by use case, not by recency.

If you're still unsure, use v4. The default exists for a reason.

Generating GUIDs by Version and Language

Language / toolv4 (default)v5 (deterministic)v7 (ordered)
PowerShell[guid]::NewGuid()
C# / .NETGuid.NewGuid()Guid.CreateVersion7() (.NET 9+)
Pythonuuid.uuid4()uuid.uuid5(uuid.NAMESPACE_URL, 'name')uuid.uuid7() (3.14 beta) / lib
JavaScriptcrypto.randomUUID()(npm uuid v11+)
Node.js (uuid lib)uuid.v4()uuid.v5('name', NAMESPACE)uuid.v7()
SQL ServerNEWID()
PostgreSQLgen_random_uuid()(extension)

A few notes: native v7 support is still landing in standard libraries as of 2026. The Node.js uuid package (v11+) and .NET 9 ship it natively; Python adds uuid.uuid7() in 3.14; older runtimes need a library. v5 support is nearly universal because it's pure SHA-1 math with no entropy source required.

FAQ

Will v7 replace v4 as the default?

No. v4 stays the general default. v7 only wins when the GUID is an ordered primary key — for most other uses (session tokens, request IDs, content hashes, anything non-database) v4's randomness is not a drawback, and v7's timestamp lead would just leak timing information for no benefit.

Is v1 still safe to use?

No. v1 embeds your network card's MAC address, which is a persistent hardware fingerprint. Microsoft itself removed v1 from Office telemetry after researchers traced machines across documents via embedded GUIDs. For new code, avoid v1 entirely; for legacy v1, plan a migration to v7.

What's the difference between v3 and v5?

Both are deterministic namespace hashes (same input → same GUID). v3 uses MD5, v5 uses SHA-1. MD5 has practical collision attacks, so v3 is considered broken for integrity purposes and was deprecated in favor of v5. There is no reason to generate v3 today.

Can I convert a v4 GUID to v7?

No. The version isn't a label you can swap — each version uses completely different generation logic. v4 has no timestamp to extract, so the only way to "get a v7" is to generate a new one. If you need to migrate a v4 primary key column to v7, you're really adding a new column and rewriting it.

Does .NET support v7 natively?

Yes. Guid.CreateVersion7() was added in .NET 9 (released November 2024). If you're on .NET 8 or earlier, use the GenVault or UUIDv7 NuGet packages, or upgrade.

QuickGUID: Generate v4 & v7, Convert Any Format

For day-to-day GUID work, QuickGUID is a native Windows toolbox that covers the full workflow:

  • Batch generation of v4 or v7, up to 1,000 at a time
  • 10+ format conversion: standard, no hyphens, braces, Base64, C byte array, DEFINE_GUID macro — all with live preview
  • Smart extraction: paste logs or source code, automatically find and convert every GUID
  • Live decorators: quotes, prefixes/suffixes, case — toggle globally and copy directly

Completely free, 100% offline.

In Closing

The versioning system exists because different jobs need different guarantees: v4 gives you untraceable randomness, v5 gives you reproducibility, v7 gives you ordering. Default to v4, reach for v7 on database keys, and use v5 when identical inputs must produce identical GUIDs.

New to GUIDs? Start with What Is a GUID? for the basics of structure, the hyphen format, and why 128 bits is enough to make collisions a non-issue in practice.