UUID v4 vs UUID v1: Which Version Should You Use?
Introduction
When architecting distributed systems, database schemas, or public APIs, choosing the right identifier strategy is one of the most critical decisions an engineering team makes. Under the RFC 4122 and updated RFC 9562 specifications, the two most historically prominent variants are UUID Version 1 and UUID Version 4.
At first glance, both versions look identical: a 36-character hexadecimal string separated into five hyphen-delimited groups (such as 6ba7b810-9dad-11d1-80b4-00c04fd430c8 vs 550e8400-e29b-41d4-a716-446655440000).
However, under the hood, their generation algorithms, security profiles, performance characteristics, and architectural use cases could not be more different:
- UUID v1 is a time-based and hardware-bound identifier that embeds your machine's physical MAC address and creation timestamp.
- UUID v4 is a purely random, cryptographically secure identifier that offers complete anonymity and decentralized generation across independent nodes.
In this comprehensive guide, we will break down the structural mechanics of UUID v1 and UUID v4, compare their strengths and weaknesses across a head-to-head matrix, analyze the critical privacy flaws of Version 1, evaluate database B-Tree index performance, and provide clear recommendations on which version you should deploy in production today.
If you are new to UUIDs, be sure to review our foundational guide on What Is UUID? Complete Guide for Developers.
What Is UUID v1?
A UUID v1 is a 128-bit identifier generated by combining the host system's hardware MAC address, a 60-bit high-resolution timestamp, and a 14-bit clock sequence counter.
The Anatomy of UUID v1
The 128 bits of a UUID v1 are distributed across five distinct structural components:
- Timestamp (60 bits total): Measures the number of 100-nanosecond intervals since the start of the Gregorian calendar reform (October 15, 1582 at 00:00:00.000 UTC). This timestamp is split across three fields:
time_low(32 bits / 8 hex digits): The lowest-order bits of the timestamp.time_mid(16 bits / 4 hex digits): The middle bits of the timestamp.time_hi_and_version(16 bits / 4 hex digits): The 12 highest bits of the timestamp, prefixed with the 4-bit version number (0001or1).
- Clock Sequence (14 bits + 2-bit Variant): A state counter designed to prevent duplicate IDs if the system clock is set backward or if the machine generates multiple UUIDs within the same 100-nanosecond window. The first 2 bits specify the RFC 4122 variant (
10_2). - Node ID (48 bits / 12 hex digits): The IEEE 802 physical MAC address of the network interface card (NIC) on the machine where the UUID was minted.
Dissecting an Example UUID v1
Consider the following canonical UUID v1 string:
6ba7b810-9dad-11d1-80b4-00c04fd430c8
Let us break down each segment:
| Segment | Hex Value | Field Representation | Analysis |
|---|---|---|---|
| Group 1 | 6ba7b810 | time_low | Lowest 32 bits of the 60-bit Gregorian timestamp. |
| Group 2 | 9dad | time_mid | Middle 16 bits of the timestamp. |
| Group 3 | 11d1 | time_hi_and_version | Version 1 followed by the highest 12 bits of the timestamp (1d1). |
| Group 4 | 80b4 | variant_and_clock_seq | RFC variant indicator (8) and clock sequence (0b4). |
| Group 5 | 00c04fd430c8 | node | Physical MAC address (00:C0:4F:D4:30:C8, registered to Dell Computer Corp). |
Because the timestamp and node address are explicitly encoded, anyone with access to this UUID v1 can extract the exact millisecond and the exact physical machine that produced it.
What Is UUID v4?
A UUID v4 is an identifier generated almost entirely from cryptographically strong pseudo-random numbers (CSPRNG).
Instead of querying system clocks, hardware network interfaces, or maintaining shared state counters, UUID v4 fills 122 bits with pure cryptographic entropy.
The Anatomy of UUID v4
Out of the 128 total bits in a UUID v4:
- 4 bits are fixed in the third group to declare Version 4 (
0100in binary / hex4). - 2 bits are fixed in the fourth group to declare the RFC 4122 variant (
10in binary / hex8,9,a, orb). - 122 bits are pure pseudo-random entropy.
The Scale of 122 Random Bits
A pool of 122 random bits yields:
$$2^{122} \approx 5.3169 \times 10^{36} \text{ distinct identifiers}$$
In practical software engineering:
- To achieve a $50%$ probability of a single collision, a distributed cluster would need to generate 1 billion UUIDs every second for approximately 85 consecutive years.
- If every person on Earth generated 1 million UUIDs per second, it would take centuries to encounter a duplicate.
Because UUID v4 does not link to timestamps or hardware MAC addresses, it is completely anonymous, impossible to reverse-engineer, and safe to expose in public web URLs and API endpoints.
Need valid random UUIDs for testing or development? Generate single or bulk RFC-compliant identifiers in your browser with our free UUID v4 Generator.
UUID v4 vs UUID v1: Head-to-Head Comparison
To understand how UUID v1 and UUID v4 differ across critical engineering criteria, examine the detailed comparison matrix below:
| Feature / Metric | UUID v1 (Time-Based) | UUID v4 (Random) | Winner / Recommendation |
|---|---|---|---|
| Generation Source | System Clock + Clock Sequence + Hardware MAC Address | CSPRNG (Cryptographically Secure Pseudo-Random Number Generator) | UUID v4 (Zero dependencies) |
| Privacy & Security | ❌ High Risk: Leaks physical MAC address and exact creation timestamp | ✅ High Security: 100% anonymous; zero hardware or time metadata exposed | UUID v4 |
| Predictability & Guessability | ⚠️ Predictable: Sequential timestamps make future/adjacent IDs easy to guess | ✅ Unguessable: High-entropy random distribution prevents scraping | UUID v4 |
| Database B-Tree Sorting | ⚠️ Semi-sequential: Natural chronological sorting (with byte swapping) | ❌ Non-sequential: Random insertions cause B-Tree index fragmentation | UUID v1 (or modern UUID v7) |
| Collision Risk | Depends on clock monotonicity and unique MAC addresses | $1 \text{ in } 5.3 \times 10^{36}$ (negligible mathematical probability) | UUID v4 (Safe across cloud nodes) |
| Virtualization & Container Safety | ⚠️ Fragile: Cloned Docker containers or VMs often share identical MAC addresses | ✅ Safe: Independent entropy pools on every virtual container | UUID v4 |
| Generation Speed | Moderate (Requires clock sync locks and NIC lookups) | Very Fast (High-throughput OS entropy buffers) | UUID v4 |
| Standard Support | RFC 4122 (Legacy) | RFC 4122 & RFC 9562 (Universal Industry Standard) | UUID v4 |
Deep Dive: The Critical Privacy & Security Flaw of UUID v1
The most significant reason software architects actively avoid UUID v1 in modern web applications is information leakage.
1. Physical Hardware & Network Fingerprinting
In UUID v1, the final 48 bits (Group 5) contain the physical MAC address of the network interface card that created the record.
When you publish a UUID v1 in a public REST API endpoint (such as GET /api/documents/6ba7b810-9dad-11d1-80b4-00c04fd430c8):
- Network Hardware Identification: Any user can decode the MAC address (
00:C0:4F:D4:30:C8). The first 24 bits represent the Organizationally Unique Identifier (OUI), revealing the hardware manufacturer (e.g., Dell, HP, Cisco, or Apple). - Server Clustering Exposure: If you run an internal cluster of backend servers, an attacker can determine which specific machine processed which request and map the internal topology of your infrastructure.
- Cross-Service Tracking: If the same server generates UUIDs for different users, clients, or tenants, an adversary can correlate records across separate systems and link anonymized datasets back to a single physical device.
Historical Precedent: The Melissa Virus
The privacy danger of UUID v1 is not theoretical. In 1999, the author of the infamous Melissa computer virus was tracked down and arrested by federal investigators partly because Microsoft Word documents created GUIDs (UUID v1) containing the author's physical Ethernet card MAC address.
2. Timestamp Reverse-Engineering & Sequence Scraping
Because UUID v1 stores high-precision timestamps:
- A competitor can inspect order confirmation URLs (
/orders/{uuid}) to determine the exact date, hour, minute, and second an order was placed. - Malicious actors can calculate the delta between two captured UUIDs to deduce transaction frequency and business volume.
- Knowing the timestamp and MAC address drastically narrows the search space for brute-forcing adjacent record IDs.
Database Performance: The B-Tree Indexing Dilemma
For years, developers chose UUID v1 over UUID v4 specifically for database primary key performance. Let us examine why this debate existed—and how modern databases handle it today.
Why UUID v4 Hurts Large B-Tree Indexes
Most relational databases (such as PostgreSQL and MySQL InnoDB) use B-Tree indexes for primary keys. B-Trees perform optimally when new records append sequentially at the right-hand edge of the index tree:
- Random Insertion Overhead: Because UUID v4 generates random hexadecimal values, each new
INSERTlands at an unpredictable location in the index. - Frequent Page Splits: When a target B-Tree node page is full, the database engine must split the page in half, move existing rows to disk, and rebalance the tree.
- Buffer Pool Thrashing: As table sizes exceed available RAM (e.g., tables with >10–20 million rows), the database cannot keep the entire B-Tree index in memory. Random writes force frequent disk reads and writes, causing write throughput to drop sharply.
Why UUID v1 Was Used (and Why It Was Flawed)
Because UUID v1 contains a 60-bit timestamp, engineers hoped it would provide natural sequential ordering.
However, RFC 4122 structured UUID v1 with the least significant time bits first (time_low in Group 1, followed by time_mid, with time_hi in Group 3). Consequently, consecutive UUID v1 strings do not sort chronologically as plain strings!
To achieve true sequential B-Tree performance with UUID v1, developers had to write custom database functions or byte-swapping triggers to reorder the fields before storing them in binary format.
Modern Alternative: Why UUID v7 Replaces Both v1 and v4
Recognizing the flaws of UUID v1 (privacy leaks and scrambled timestamps) and UUID v4 (random B-Tree index fragmentation), the IETF published RFC 9562, introducing UUID Version 7.
How UUID v7 Works:
UUID v7 provides the ultimate architectural compromise:
$$\text{UUID v7} = \underbrace{\text{48-bit Unix Timestamp (ms)}}{\text{Chronologically Sorted}} + \underbrace{\text{4-bit Version (7)}}{\text{RFC Header}} + \underbrace{\text{12-bit Sub-ms Counter / Entropy}}{\text{Fine-grained Time}} + \underbrace{\text{2-bit Variant}}{\text{RFC Spec}} + \underbrace{\text{62-bit CSPRNG Random Entropy}}_{\text{Collision-Proof}}$$
The Advantages of UUID v7:
- 100% Chronologically Sortable: The most significant 48 bits represent standard Unix epoch time in milliseconds. Natural string sorting equals natural chronological sorting.
- Optimal B-Tree Performance: High-throughput
INSERToperations append cleanly to the right side of B-Trees with minimal page splits. - Zero Privacy Risks: Does not use MAC addresses or hardware identifiers.
- Standardized Compatibility: Uses standard 128-bit / 36-character formatting, making it a drop-in replacement for existing UUID columns in PostgreSQL, MySQL, SQLite, and MongoDB.
When Should You Use UUID v4 vs UUID v1?
Here is the straightforward decision framework for modern software architectures:
Choose UUID v4 When:
- You need general-purpose unique identifiers for entities, users, or resources.
- Identifiers are exposed in public URLs, REST APIs, GraphQL queries, or client-side SPAs.
- You are generating IDs on frontend clients, mobile apps, or serverless functions.
- You are issuing authentication tokens, password reset tokens, or session IDs.
- You are deploying inside Docker containers, Kubernetes clusters, or multi-tenant clouds where MAC addresses are virtualized or cloned.
Choose UUID v1 Only When:
- You are maintaining a legacy database or enterprise system that explicitly mandates RFC 4122 Version 1.
- You are operating in a closed, air-gapped internal network where hardware tracking is an intentional requirement.
Choose UUID v7 When:
- You need primary keys in large relational databases (PostgreSQL, MySQL InnoDB, CockroachDB) that require high-throughput sequential write performance without sacrificing privacy or distributed generation.
Code Examples: Generating & Working with UUIDs
Let us examine how to generate and handle both UUID v1 and UUID v4 across modern programming environments.
1. TypeScript & Node.js
Modern Node.js includes native cryptographically secure UUID v4 generation built into the crypto module, while the popular uuid npm package supports all versions:
import crypto from "crypto";
import { v1 as uuidv1, v4 as uuidv4 } from "uuid";
// 1. Native Node.js UUID v4 generation (Fastest & Zero Dependencies)
const nativeV4Id: string = crypto.randomUUID();
console.log("Native UUID v4:", nativeV4Id);
// Output: "3b241101-e2bb-4255-8caf-4136c566a964"
// 2. Library-based UUID v4 generation
const libV4Id: string = uuidv4();
console.log("Library UUID v4:", libV4Id);
// 3. UUID v1 generation (Requires MAC address resolution)
const v1Id: string = uuidv1();
console.log("UUID v1 (Time-based):", v1Id);
// Output: "6c84fb90-12c4-11e1-840d-7b25c5ee775a"
// Function to inspect and verify UUID version
export function getUuidVersion(uuidString: string): number | null {
const match = uuidString.match(/^[0-9a-f]{8}-[0-9a-f]{4}-([1-8])[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i);
return match ? parseInt(match[1], 10) : null;
}
console.log("Version check for nativeV4Id:", getUuidVersion(nativeV4Id)); // 4
console.log("Version check for v1Id:", getUuidVersion(v1Id)); // 1
2. Python
Python includes full standard library support for UUID v1, v3, v4, and v5 in the built-in uuid module:
import uuid
# Generate a random UUID v4
random_id = uuid.uuid4()
print(f"UUID v4: {random_id}")
print(f"Version: {random_id.version}") # 4
print(f"Hex representation: {random_id.hex}")
# Generate a time-based UUID v1
time_id = uuid.uuid1()
print(f"UUID v1: {time_id}")
print(f"Version: {time_id.version}") # 1
# Extract the embedded MAC address and timestamp from UUID v1
print(f"Extracted Node (MAC): {hex(time_id.node)}")
print(f"Extracted 100ns Timestamp: {time_id.time}")
3. Go (Golang)
Using the official github.com/google/uuid package:
package main
import (
"fmt"
"github.com/google/uuid"
)
func main() {
// Generate UUID v4 (Random)
v4Id, err := uuid.NewRandom()
if err != nil {
panic(err)
}
fmt.Printf("UUID v4: %s (Version: %d)\n", v4Id.String(), v4Id.Version())
// Generate UUID v1 (Time + MAC)
v1Id, err := uuid.NewUUID()
if err != nil {
panic(err)
}
fmt.Printf("UUID v1: %s (Version: %d)\n", v1Id.String(), v1Id.Version())
}
Frequently Asked Questions (FAQ)
Can a UUID v4 accidentally generate a valid UUID v1?
No. Every UUID version is hard-coded with its version number in bits 48 through 51 (the first character of the third segment). A UUID v4 will always have a 4 in position 15 (xxxx-xxxx-4xxx-xxxx-xxxxxxxxxxxx), whereas a UUID v1 will always have a 1 (xxxx-xxxx-1xxx-xxxx-xxxxxxxxxxxx).
Why do some UUID v1 implementations use a random node instead of a MAC address?
To mitigate the privacy vulnerability of MAC address leakage, RFC 4122 allows implementations to substitute a 48-bit pseudo-random number for the node ID, provided the multicast bit (the least significant bit of the first octet) is set to 1. However, this defeats the primary original purpose of v1 (hardware-based uniqueness) while still retaining the scrambled timestamp layout.
Is UUID v4 completely collision-proof?
In practical software engineering, yes. While the collision probability is non-zero mathematically ($1 / 2^{122}$), it is so infinitesimally small that no production system will ever generate duplicates under proper CSPRNG operation.
How do I check what version a UUID string is?
Inspect the 13th hexadecimal digit (the character immediately following the second hyphen). If the character is 4, it is a UUID v4. If it is 1, it is a UUID v1.
Conclusion & Summary Checklist
When building modern web applications, microservices, and distributed cloud backends:
- Default to UUID v4 for all general-purpose identifiers, public API routes, user IDs, authentication tokens, and distributed messaging keys.
- Avoid UUID v1 due to its severe privacy risks, hardware MAC address leakage, and fragile behavior in virtualized cloud environments.
- Adopt UUID v7 whenever you require high-volume database primary keys that need chronological sortability and maximum B-Tree write efficiency.
Ready to test and generate RFC-compliant UUIDs for your project? Try our fast, secure, and client-side UUID Generator Tool.