Developer Reference · RFC 4122 & RFC 9562

What is a UUID?
The Complete Developer Guide

Everything you need to know about Universally Unique Identifiers — format, versions, bit structure, collision probability, and when to use each version in 2026.

Section 1

UUID Definition

A UUID (Universally Unique Identifier) is a 128-bit label used to uniquely identify information in computer systems. The defining property of a UUID is that it can be generated by any computer, independently, without coordinating with a central authority, and still be practically guaranteed never to duplicate an identifier generated anywhere else in the world.

The standard is formally defined in two RFCs. RFC 4122 (published July 2005) introduced the original four versions: v1, v3, v4, and v5. RFC 9562 (published May 2024) superseded RFC 4122 and added versions v6, v7, and v8 along with the Nil and Max special-purpose UUIDs.

You will often see UUID used interchangeably with GUID (Globally Unique Identifier), which is Microsoft’s term for its implementation. The underlying standard is identical; some Microsoft implementations differ in byte-order representation for certain fields.

💡

Why “Universally Unique”?

Unlike a sequential database ID that requires a central counter, a UUID is designed so that any two systems can independently generate an identifier without any communication between them and still be confident the IDs will not collide. This decentralization is what makes UUIDs essential in distributed systems, microservices, and offline-first applications.

Section 2

UUID Format and Anatomy

A UUID is represented as 32 lowercase hexadecimal digits arranged in five groups separated by hyphens, following an 8-4-4-4-12 pattern. The total length is always 36 characters including hyphens, or 32 characters without.

f47ac10b58cc4372a5670e02b2c3d479
8 hex digits (32 bits)Low time or random data
4 hex digits (16 bits)Mid time or random data
4 hex digits (16 bits)Version + high time/random
4 hex digits (16 bits)Variant + clock sequence
12 hex digits (48 bits)Node (MAC/random)

Version and Variant Bits

Two specific character positions in every UUID carry structural meaning regardless of version:

  • Position 13 (character at index 14 in the full string) — the version digit. A UUID v4 always has 4 here; a v7 always has 7. This is how you identify a UUID’s version at a glance.
  • Position 17 (character at index 19 in the full string) — the variant digit. For all RFC 4122/9562-compliant UUIDs, this is always 8, 9, a, or b. This confirms the UUID follows the standard rather than older or proprietary UUID formats.

Bit Layout of a UUID v4

32 bits
time_low
16 bits
time_mid
4b
ver
12 bits
random
2b
var
14 bits
random
48 bits — random node
 
Total: 128 bits = 122 random bits + 4 version bits + 2 variant bits

Validation Regex

A simple regular expression for validating any RFC-compliant UUID (versions 1–8):

/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i

The [1-8] anchors the version digit to currently-defined versions. The [89ab] anchors the variant to the RFC 4122/9562 range.

Section 3

All 8 UUID Versions Explained

RFC 4122 defined four versions in 2005. RFC 9562 added three more in May 2024. Here is what each version does, how it generates its bits, and when to use it.

VersionAlgorithmDeterministicTime-SortableRFC2026 Status
v160-bit timestamp (100ns since Oct 1582) + MAC address + clock sequenceNoPartially4122Use with caution
v3MD5 hash of namespace UUID + name stringYesNo4122Prefer v5
v4122 cryptographically random bitsNoNo4122Recommended
v5SHA-1 hash of namespace UUID + name stringYesNo4122Recommended
v6Reordered v1 timestamp (sortable) + MAC/random nodeNoYes9562v1 migration
v748-bit Unix millisecond timestamp + 74 random bitsNoYes9562Recommended 2026
v8Fully custom layout defined by implementationDependsDepends9562Experimental
NilAll 128 bits set to zeroYes9562Special value
MaxAll 128 bits set to one (all F)Yes9562Special value

UUID v1 — Timestamp + MAC

UUID v1 uses a 60-bit timestamp counting 100-nanosecond intervals since October 15, 1582 (the Gregorian calendar reform date). The timestamp is combined with a 14-bit clock sequence (to handle sub-100ns generation rates or clock adjustments) and a 48-bit node value derived from the generating machine’s MAC address.

⚠️

Privacy risk in user-facing applications

Because v1 embeds the MAC address of the generating machine, any party who receives a v1 UUID can potentially trace it back to the machine that created it. Do not use v1 in user-facing systems where you need to protect the generating machine’s identity.

UUID v3 and v5 — Name-Based (Deterministic)

v3 and v5 both generate UUIDs deterministically from a namespace UUID and a name string. Given the same namespace and name, they always produce the same UUID — making them useful for deduplication and content-addressable IDs. v3 uses MD5; v5 uses SHA-1. Always prefer v5: MD5 is cryptographically broken, and v5 produces more collision-resistant output.

Four standard namespaces are defined in RFC 4122: DNS (6ba7b810-9dad-11d1-80b4-00c04fd430c8), URL, OID, and X.500 DN. You can also define your own namespace UUID for your application domain.

UUID v4 — Random (General Purpose)

UUID v4 is the most widely used version. It fills 122 bits with cryptographically random data (the remaining 6 bits are fixed for version and variant markers). With 2¹²² possible values — roughly 5.3 undecillion — collisions are astronomically unlikely at any real-world scale.

Use v4 for: API resource identifiers, session tokens, object names, file names, and any ID where you specifically do not want to encode creation time.

UUID v6 — Time-Ordered v1 Replacement

UUID v6 reorganizes the v1 timestamp fields so the most significant bits come first, making v6 UUIDs sort correctly by generation time. It is field-compatible with v1 (the timestamp fields can be extracted using the same logic), making it a natural migration path for systems already using v1.

UUID v7 — Unix Timestamp (2026 Default for Primary Keys)

UUID v7 encodes a 48-bit Unix timestamp in milliseconds in the most significant bits, followed by 74 bits of random data. This design makes v7 UUIDs monotonically increasing within each millisecond and time-sortable across machines without coordination.

Why v7 is the recommended choice for database primary keys in 2026

B-tree indexes (used by PostgreSQL, MySQL, SQLite, and most other relational databases) perform best when new values are inserted in roughly ascending order. Fully random v4 UUIDs cause page splits and index fragmentation at scale. UUID v7’s time-prefixed structure eliminates this problem while retaining 74 bits of randomness — more than sufficient for collision safety. PostgreSQL 18 ships native uuidv7() support, and frameworks including Laravel 11+ and Rails 8+ now default to v7.

UUID v8 — Custom Layout

UUID v8 is a wildcard version: RFC 9562 defines only the version (bits 48–51) and variant (bits 64–65) fields. All other 122 bits are implementation-defined. Use v8 when you need UUID-shaped identifiers that embed application-specific structured data — for example, a shard ID, tenant ID, or feature flags packed into the bit fields. It is experimental for most use cases.

Nil and Max UUIDs

The Nil UUID (00000000-0000-0000-0000-000000000000) has all 128 bits set to zero. The Max UUID (ffffffff-ffff-ffff-ffff-ffffffffffff) has all 128 bits set to one. Both are defined in RFC 9562 as sentinels — Nil to represent “no UUID” or an unset field, Max to represent a boundary or wildcard value (for example, the upper bound in a range query).

Section 4

Which UUID Version Should You Use?

SituationRecommended VersionReason
Database primary key (new project, 2026)v7Time-sortable, B-tree friendly, 74-bit random node. PostgreSQL 18 native.
API resource ID, opaque token, general IDv4Fully random, no time leakage, universally supported.
Password-reset link, CSRF token, short-lived secretv4 (or dedicated secret generator)No timestamp exposure. Note: UUID alone is not a cryptographic secret — use purpose-built secret generation for high-security tokens.
Content-addressable or deduplicated ID from a known namev5Deterministic SHA-1 hash of namespace + name. Same input always yields same UUID.
Migrating from v1 without changing field widthsv6Field-compatible v1 replacement with time-sortable bit order.
Legacy system already using v1v1Keep for compatibility if MAC leak risk is acceptable and system is not user-facing.
Placeholder / “no ID set” sentinelNilAll zeros, recognized by all UUID-aware systems as the null/unset value.
Custom structured identifier (shard ID embedded, etc.)v8All non-version/variant bits are yours to define.
🔒

Do not use any UUID version as a standalone secret

UUIDs are designed for uniqueness, not unguessability. A UUID alone should never be your only authentication factor, password, or high-value API key. For security-critical secrets, use a CSPRNG with sufficient entropy and appropriate access controls.

Section 5

UUID Collision Probability

A UUID v4 has 122 bits of actual randomness (6 bits are fixed for version and variant markers). That gives 2¹²² possible values:

5,316,911,983,139,663,491,615,228,241,121,400,000
Possible UUID v4 values (2¹²² ≈ 5.3 × 10³⁶)

To put that in perspective: if every person on Earth (8 billion people) generated 600 million UUIDs each, the probability of even a single collision anywhere in that entire set would still only be approximately 50%. At the scale of any real application — even large distributed systems generating millions of IDs per day — treat v4 collisions as a non-event.

The precise formula for the probability p of at least one collision when generating n UUIDs from a space of N values is given by the birthday problem approximation:

p(n) ≈ 1 − e−n(n−1) / (2N)

For a 1-in-a-billion collision probability with UUID v4, you would need to generate approximately 2.6 × 10¹⁷ UUIDs — a number no practical system approaches.

💬

Has a UUID collision ever actually occurred in production?

There are no credible documented cases of a random UUID v4 collision in production caused by the randomness algorithm itself. The far more common source of “UUID collision” bugs is incorrect implementation — reusing a UUID from a test, serializing/deserializing incorrectly, or using a non-CSPRNG source for the random bits.

Section 6

UUID History and RFC Timeline

UUIDs did not originate with the IETF. They were first developed in the context of the Apollo Network Computing System in the late 1980s, then adopted and extended by the Open Software Foundation (OSF) for the Distributed Computing Environment (DCE) in 1990.

1
1980s — Apollo / OSF

Origins in Distributed Computing

Apollo Computer’s NCS introduced unique identifiers for distributed RPC systems. OSF adopted and formalized the concept for DCE, defining the time-based algorithm that became UUID v1.

2
1997 — ITU-T and ISO

First Formal Standard

ISO/IEC 11578:1996 and ITU-T X.667 published the first formal international UUID standards, covering the time-based and random algorithms.

3
July 2005 — RFC 4122

IETF Standardizes UUID

RFC 4122, authored by Paul Leach, Michael Mealling, and Rich Salz, became the definitive Internet standard for UUIDs. It formally defined versions 1, 3, 4, and 5. This document remained the authoritative reference for 19 years.

4
2021–2024 — IETF Working Group

New Versions Drafted

As cloud-native, distributed, and time-series workloads grew, the community recognized the need for time-sortable UUIDs that avoided the B-tree fragmentation problems of v4. The IETF UUIDv6 working group drafted v6, v7, and v8.

5
May 2024 — RFC 9562

RFC 9562 Supersedes RFC 4122

RFC 9562 formally obsoleted RFC 4122 and introduced UUID v6, v7, and v8, plus the Nil and Max special values. PostgreSQL 18, Laravel 11, Rails 8, and major UUID libraries rapidly added native support for v7.

Section 7

Real-World UUID Use Cases

UUIDs appear across virtually every layer of modern software. Here are the most common applications and the version typically used for each.

Use CaseVersionWhy
Relational database primary keys (PostgreSQL, MySQL)v7Sequential-enough for B-tree index locality; no auto-increment coordination needed across replicas or shards.
REST/GraphQL API resource identifiersv4Opaque — does not expose creation time or count of resources to clients.
File and object storage naming (S3, GCS)v4Unique, URL-safe (when hyphens are removed or kept), no central counter needed.
Message queue deduplication IDsv4 or v7v4 for opaque dedup keys; v7 where time-ordering aids message replay analysis.
Session and request tracing IDsv7Timestamp prefix enables log sorting and time-range queries without a separate timestamp field.
Event sourcing / event IDsv7Events sort naturally by ID, enabling efficient range queries over event streams.
Content-addressable cache keys (CDN, Redis)v5Deterministic: same URL or content hash always maps to the same UUID cache key.
Idempotency keys in payment systemsv4Random, client-generated, no information disclosure, simple to generate client-side.
Device and hardware identifiers (BLE, IoT)v4 or v1v4 for generated device IDs; v1 historically used where MAC-based traceability was acceptable.
Minecraft player and entity UUIDsv4Java Edition uses the standard UUID format for player and entity identification; username-to-UUID mapping uses a v3-like deterministic hash via the Mojang API.

Section 8

Frequently Asked Questions

Yes, for practical purposes. GUID (Globally Unique Identifier) is Microsoft’s term for its implementation of the same 128-bit standard. The bit structure and format are identical. Some older Microsoft implementations (notably COM/DCOM) store certain fields in a different byte order in binary representations, but the canonical hyphenated string representation is the same.
A UUID is always 36 characters in its canonical hyphenated form (32 hexadecimal digits + 4 hyphens), or 32 characters without hyphens. In binary form it is exactly 16 bytes (128 bits). Databases that store UUIDs as a native UUID type use 16 bytes; storing as a VARCHAR(36) uses 36 bytes of character storage.
No. The hexadecimal digits in a UUID are case-insensitive: 550e8400-e29b-41d4-A716-446655440000 and 550e8400-e29b-41d4-a716-446655440000 represent the same UUID. RFC 9562 recommends outputting UUIDs in lowercase, but comparison must always be case-insensitive. Inconsistent casing is a common source of bugs in string-based UUID comparisons.
No. A UUID is a 128-bit unsigned integer. It has no sign bit. However, some programming languages represent UUIDs internally as signed 64-bit integer pairs, which means the raw numeric value can appear negative when accessed through certain APIs. This is a language representation detail, not a property of the UUID itself. Always use proper UUID types or unsigned integers when working with UUID values programmatically.
UUID v4 is entirely random (122 bits of random data). UUID v7 starts with a 48-bit Unix millisecond timestamp, making it time-sortable. v4 is better when you need opaque identifiers that reveal no timing information. v7 is better for database primary keys because its monotonic ordering reduces B-tree index fragmentation. For a brand-new project with a relational database in 2026, default to v7. For API tokens, session IDs, or any context where timestamp exposure is undesirable, use v4.
Use the database’s native UUID type when available: PostgreSQL has a native uuid type (16 bytes, indexed efficiently); MySQL 8+ has a UUID() function but stores as VARCHAR unless you use BINARY(16) explicitly; SQL Server has uniqueidentifier; SQLite has no native type so use TEXT(36) or BLOB(16). Storing as BINARY(16) saves space versus VARCHAR(36) and is faster to index, but requires conversion on read/write. For new projects, use the native type when your database supports it.
The Nil UUID (00000000-0000-0000-0000-000000000000) is a special UUID defined in RFC 9562 with all 128 bits set to zero. It is used as a sentinel value to indicate “no UUID” or an unset/null UUID field. It should never appear as a legitimate identifier in your data — check for it explicitly when validating input to avoid treating an uninitialized UUID as a valid entity reference.
UUID v4 uses a cryptographically secure random number generator (CSPRNG) for its 122 random bits when generated by compliant libraries. This means the output is unpredictable in the cryptographic sense. However, a UUID v4 is not a cryptographic secret by itself — it provides uniqueness, not confidentiality or authentication. Do not use a UUID as a password hash, HMAC key, or sole authentication credential. For high-security tokens, use a dedicated secret generation function that outputs sufficient entropy and is designed for security contexts.

Ready to Generate a UUID?

Use our free browser-based generator for all 8 versions — v4, v7, v1, v3, v5, v6, v8, Nil, and Max. Nothing is sent to a server.

Generate UUID Now