UUID v1 vs v4: Which Should You Use?
UUIDs (Universally Unique Identifiers) are the backbone of distributed systems. Every database, API, and microservice uses them. But not all UUID versions serve the same purpose. This guide compares UUID v1 and v4, covers their security implications, and introduces UUID v7 as a modern alternative — all based on the specifications in RFC 4122 and the newer RFC 9562 (2024).
UUID Structure
All UUIDs follow the same 128-bit format displayed as 32 hexadecimal characters in five groups: 8-4-4-4-12. The version number is encoded in the first character of the third group, and the variant (always 8, 9, a, or b for RFC 4122) is the first character of the fourth group.
550e8400-e29b-41d4-a716-446655440000
^version ^variantUUID v1: Time-Based
UUID v1 combines a timestamp with the generating machine's MAC address. The timestamp is measured in 100-nanosecond intervals since October 15, 1582 (the Gregorian calendar reform date). The MAC address occupies the last 12 hex characters (bytes 10–15).
When v1 is appropriate
- Distributed event logging where time-ordering matters
- Cassandra-style time-series databases (though v7 is now preferred)
- Legacy systems that require MAC address traceability
When v1 is wrong
- Any identifier exposed in a URL or API response. The MAC address in bytes 10–15 can fingerprint the generating machine. This is a real security concern documented by OWASP.
- Privacy-sensitive applications where hardware identifiers must not leak
- Multi-tenant systems where infrastructure topology should be hidden
UUID v4: Random
UUID v4 fills 122 of its 128 bits with cryptographically random data. The remaining 6 bits are fixed: 4 for the version (0100) and 2 for the variant (10). This gives approximately 5.3 × 1036 possible values.
In browsers, UUID v4 is generated natively via crypto.randomUUID(). In Node.js 14.17+, use require('crypto').randomUUID().
Head-to-Head Comparison
| Feature | UUID v1 | UUID v4 |
|---|---|---|
| Randomness | ~62 bits (clock sequence) | 122 bits |
| Time-sortable | Yes | No |
| Contains MAC address | Yes (bytes 10–15) | No |
| Safe for public APIs | No | Yes |
| Database index performance | Good (sequential) | Poor (random scatter) |
| Collision probability (1B UUIDs) | Near zero | ~6.1 × 10-19 |
| Generation requires | Clock + MAC | CSPRNG only |
The Database Performance Problem
UUID v4's randomness is a strength for uniqueness but a weakness for database performance. B-tree indexes work best with sequential inserts. Random UUIDs cause page splits, fragmenting the index and increasing I/O. This matters at scale — millions of rows with UUID v4 primary keys can show 2-3x slower insert performance compared to sequential identifiers.
UUID v7: The Modern Alternative
RFC 9562 (published April 2024) defines UUID v7, which uses Unix timestamp milliseconds in the first 48 bits. This makes v7 UUIDs lexicographically sortable by creation time while keeping 74 bits of randomness — no MAC address exposure.
| Feature | v1 | v4 | v7 |
|---|---|---|---|
| Time-sortable | Yes | No | Yes |
| Exposes MAC | Yes | No | No |
| DB index friendly | Good | Poor | Excellent |
| Random bits | ~62 | 122 | 74 |
Recommendation: Use UUID v7 for database primary keys when you need time-ordering. Use UUID v4 for general-purpose identifiers where ordering does not matter. Avoid UUID v1 in new projects.
Other UUID Versions
- v3 (MD5 namespace) — Deterministic: same namespace + name always produces the same UUID. Uses MD5, which has known collision vulnerabilities.
- v5 (SHA-1 namespace) — Same concept as v3 but uses SHA-1. Prefer v5 over v3 for namespace-based UUIDs.
- v6 — A reordered v1 (RFC 9562) that puts the timestamp bits in lexicographic order. Largely superseded by v7.
- v8 — Custom: the spec reserves v8 for application-defined formats. The only requirement is setting the version and variant bits correctly.
Implementation Examples
// JavaScript (browser) — UUID v4
const id = crypto.randomUUID();
// Node.js 14.17+
const { randomUUID } = require('crypto');
const id = randomUUID();
// Python
import uuid
v4_id = uuid.uuid4()
// PostgreSQL
SELECT gen_random_uuid(); -- v4For PostgreSQL, gen_random_uuid() generates v4 UUIDs natively since version 13.
Key Takeaways
- UUID v4 (random) is the safe default for most applications
- UUID v1 leaks your MAC address — avoid in public-facing systems
- UUID v7 (RFC 9562) is the modern choice for time-sortable database keys
- Random UUIDs fragment B-tree indexes — consider v7 for write-heavy tables
- Prefer v5 over v3 for namespace-based deterministic UUIDs
Need to generate UUIDs quickly? Our UUID Generator creates RFC 4122 compliant v4 identifiers using the Web Crypto API, with bulk generation up to 100 at once.
Frequently Asked Questions
- Can two UUID v4 values ever collide?
- In theory, yes. In practice, no. UUID v4 has 122 random bits, giving approximately 5.3 x 10^36 possible values. You would need to generate about 2.7 x 10^18 UUIDs before having a 50% chance of a single collision.
- Is UUID v1 safe to use in public APIs?
- No. UUID v1 embeds the generating machine's MAC address in bytes 10-15. If you expose v1 UUIDs in API responses, clients can extract the MAC address and potentially fingerprint your infrastructure. Use v4 or v7 for public identifiers.
- What is UUID v7 and should I use it?
- UUID v7 (RFC 9562, 2024) uses Unix timestamp milliseconds in the first 48 bits, making UUIDs sortable by creation time. It is the modern replacement for v1 when you need time-ordering without exposing hardware identifiers. Use v7 for database primary keys and v4 for general-purpose identifiers.