What Is a UUID?
A UUID (Universally Unique Identifier) is a 128-bit label standardized by the Open Software Foundation (OSF) and later formalized in RFC 4122 and the updated RFC 9562. It is represented as 32 hexadecimal digits displayed in five groups separated by hyphens — for example, 550e8400-e29b-41d4-a716-446655440000. The total string length is always 36 characters.
The defining property of a UUID is that it can be generated independently on any machine, at any time, without coordination with a central authority — and the probability of two UUIDs ever being identical is so astronomically small that it is treated as zero for all practical purposes.
UUID Format and Structure
Every UUID follows the xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx pattern, where M is the version digit and N is the variant digit. The five hyphen-separated groups contain 8, 4, 4, 4, and 12 hex characters respectively, encoding 32, 16, 16, 16, and 48 bits of data.
The version field (the first digit of the third group) tells you how the UUID was generated — 1 for timestamp+MAC, 4 for random, 7 for Unix epoch time. The variant field (the first digit of the fourth group) indicates the layout standard; most modern UUIDs use variant 8, 9, a, or b, indicating RFC 4122 compliance.
UUID Versions Explained
UUID v1 — Timestamp + MAC Address
Version 1 encodes a 60-bit timestamp (100-nanosecond intervals since October 15, 1582) and a 48-bit node ID (traditionally the MAC address). It is partially sortable and useful for audit trails, but exposes hardware identity. Modern implementations replace the MAC address with a random node ID for privacy.
UUID v4 — Cryptographically Random
Version 4 uses 122 bits of cryptographic randomness. It is the most widely deployed UUID version — used for user IDs, session tokens, API keys, and resource identifiers across virtually every modern web application. The collision probability is 1 in 5.3 × 10³⁶.
UUID v6 — Reordered Timestamp (RFC 9562)
Version 6 reorders the timestamp fields of v1 so that the most significant bits come first, making the UUID lexicographically sortable. It is fully backward-compatible with v1 and is defined in RFC 9562.
UUID v7 — Unix Epoch Time-Ordered (RFC 9562)
Version 7 uses a 48-bit Unix millisecond timestamp followed by 74 bits of randomness. It is the recommended choice for database primary keys because new records are always appended to the end of a B-tree index, eliminating page splits and dramatically improving INSERT performance at scale.
Why UUIDs Are Essential in Modern Architecture
In a monolithic application with a single database, auto-incrementing integers work fine. But in distributed systems — microservices, multi-region deployments, event-driven architectures — you need identifiers that can be generated independently on any node without coordination. UUIDs solve this problem completely.
Consider a scenario where you have three independent services: an order service, a payment service, and a notification service. Each needs to create records and reference them across services. With auto-increment IDs, you need a central ID service or risk collisions. With UUIDs, each service generates its own IDs independently and they are guaranteed to be globally unique.
UUIDs also prevent Insecure Direct Object Reference (IDOR) attacks. When resource IDs are sequential integers, a malicious user can enumerate resources by incrementing the ID in the URL. UUIDs are opaque and unpredictable, making enumeration attacks infeasible.
UUID vs. ULID vs. NanoID vs. GUID
GUID is Microsoft's name for UUID. Structurally identical, GUIDs are often displayed in uppercase with curly braces in Windows and .NET contexts. They are interchangeable with UUIDs in any RFC 4122-compliant system.
ULID is a 128-bit time-ordered identifier encoded in Crockford Base32, producing a 26-character URL-safe string. It is similar to UUID v7 but uses a different encoding. ULID has slightly better URL ergonomics; UUID v7 has broader native database support.
NanoID is a compact, URL-safe identifier with a customizable alphabet and length. At 21 characters with the default alphabet, it provides ~126 bits of entropy. It is ideal for short URLs and API tokens but lacks time-ordering.
How to Store UUIDs Efficiently
Storing UUIDs as VARCHAR(36) is the most common mistake. A UUID string takes 36 bytes, but the underlying data is only 16 bytes. Use native UUID types where available:
- →PostgreSQL: Native
UUIDtype — 16 bytes, indexed efficiently. - →MySQL / MariaDB: Use
BINARY(16)withUUID_TO_BIN(uuid, 1)for swap-flag optimization. - →SQL Server: Native
UNIQUEIDENTIFIERtype — 16 bytes. - →MongoDB: Use
BinDatasubtype 3 or 4 for UUID storage.
RFC 4122 and RFC 9562 — The Standards Behind UUIDs
RFC 4122, published in 2005, defined UUID versions 1 through 5 and established the canonical 8-4-4-4-12 format. It became the foundation for UUID support in every major programming language and database system.
RFC 9562, ratified by the IETF in May 2024, supersedes RFC 4122 and introduces versions 6, 7, and 8. Version 7 in particular has been widely adopted as the new standard for database primary keys, replacing the common pattern of using v4 with its associated index fragmentation problems. All UUIDs generated on this platform comply with both standards.
Generating UUIDs in Your Code
Every major language has built-in or well-supported UUID generation:
- →Node.js:
crypto.randomUUID()(native, no dependencies) - →Python:
import uuid; uuid.uuid4()(stdlib) - →Go:
github.com/google/uuidpackage - →PHP:
ramsey/uuidcomposer package - →Java:
java.util.UUID.randomUUID()(stdlib) - →C#/.NET:
Guid.NewGuid()(stdlib) - →Rust:
uuidcrate withv4feature flag
Visit the Developer Lab for copy-ready implementation snippets in 25+ languages.