UUID versions and format, on one page
A UUID is a 128-bit identifier written as 36 characters of hex — 8-4-4-4-12 — designed to be generated anywhere, by anyone, without coordination and without collisions. Eight versions exist; only three matter day to day: v4 (pure random, the default everywhere), v7 (time-sortable, the modern pick for database keys), and v5 (deterministic, hashed from a name).
This page is the reference: the format, annotated, the version table, generation snippets for JavaScript, SQL, Python, and the terminal, and the collision math. To mint UUIDs in bulk — any version, uppercase, braced, or raw bytes — use the UUID generator; for the full v4-vs-v7 decision, read UUID v4 vs v7.
The format, annotated
Every standard UUID fixes six bits: the version nibble (13th hex digit) says how it was made, and the variant nibble (17th digit, always 8, 9, a, or b) marks it as an RFC-form UUID. Everything else is payload — random bits, timestamp, or hash, depending on the version.
version nibble (here: 4)
│
0195c2f0-8f3a-4d6e-b81f-3c92a54d7e19
└──┬───┘ └─┬─┘ └─┬─┘ └┬─┘ └────┬────┘
8 hex 4 hex 4 hex │ 12 hex = 32 hex digits, 128 bits
│
variant nibble (8, 9, a, or b)All UUID versions at a glance
RFC 9562 (2024) superseded RFC 4122 and added v6, v7, and v8. Version 2 is omitted below — it was a DCE security variant that effectively nobody generates today.
| Version | Built from | When to use it |
|---|---|---|
| v1 | 60-bit Gregorian timestamp + clock sequence + MAC address | Legacy. Time-ordered but leaks the host MAC and creation time; superseded by v6/v7. |
| v3 | MD5 hash of a namespace UUID + a name | Deterministic IDs from names. Prefer v5 — same idea, SHA-1 instead of MD5. |
| v4 | 122 random bits (6 bits fixed for version + variant) | The default everywhere. What crypto.randomUUID(), Python uuid4(), and Postgres gen_random_uuid() produce. |
| v5 | SHA-1 hash of a namespace UUID + a name | Deterministic: the same namespace + name always yields the same UUID. Good for stable IDs derived from URLs or emails. |
| v6 | v1 fields reordered so timestamp bits lead | A sortable drop-in for systems already storing v1. New systems should pick v7 instead. |
| v7 | 48-bit Unix millisecond timestamp + 74 random bits | The modern choice for database keys: time-sortable, index-friendly, no MAC leak. Standardized in RFC 9562 (2024). |
| v8 | 122 bits of application-defined layout | An escape hatch: format-compliant but the content is entirely yours. Use only when v4/v7 genuinely cannot express what you need. |
Deciding between the two that matter? UUID v4 vs v7 covers index locality, timestamp leakage, and migration in depth.
Generate a UUID anywhere
crypto.randomUUID()
// "0195c2f0-8f3a-4d6e-b81f-3c92a54d7e19"
// Built in, cryptographically random. Browsers require a secure
// context (https or localhost). For v7 use the uuid package:
import { v7 as uuidv7 } from 'uuid'; // npm i uuiduuidgen # macOS & util-linux, v4
cat /proc/sys/kernel/random/uuid # Linux kernel, v4
python3 -c "import uuid; print(uuid.uuid4())"-- PostgreSQL (13+): built-in v4
SELECT gen_random_uuid();
-- PostgreSQL 18+: built-in, time-sortable v7
SELECT uuidv7();
-- MySQL: UUID() returns v1 (time + MAC) — use UUID_TO_BIN(UUID(), 1)
-- for index-friendly storage, or generate v4/v7 in the application.import uuid
uuid.uuid4() # random v4
uuid.uuid5(uuid.NAMESPACE_URL, "https://example.com") # deterministic v5How unique is a UUID, really?
A v4 UUID carries 122 random bits — about 5.3 × 10³⁶ possible values. The birthday bound says you would need roughly 2.7 × 10¹⁸ UUIDs — a billion per second for about 85 years — before the odds of even one collision reach 50%. Real-world collisions come from broken randomness (a seeded PRNG, cloned VM snapshots, a bad polyfill), never from the format itself. For v7, uniqueness within the same millisecond rests on its 74 random bits — still far beyond anything a single system generates.
UUID vs GUID vs ULID vs Nano ID
| Identifier | Shape | The short version |
|---|---|---|
| GUID | Identical to UUID — 128 bits, same format | Just Microsoft’s name for the same thing. .NET’s Guid.NewGuid() emits UUID v4. |
| ULID | 26 chars, Crockford base32, 48-bit timestamp + 80 random bits | Sortable like UUID v7 with a more compact text form. Not an IETF standard; v7 is the standardized equivalent. |
| Nano ID | 21 URL-safe chars by default, ~126 bits of randomness | Shorter, URL-friendly random IDs when you don’t need UUID’s fixed format — common for public-facing slugs. |
Make IDs, right here
Frequently asked questions
No. RFC 9562 (2024) — the standard that replaced RFC 4122 — keeps v4 fully specified and it remains the most widely generated UUID version. What changed is the recommendation for database keys: v7 is now preferred there because its leading timestamp keeps B-tree indexes appending near one hot page instead of scattering random inserts across the whole index. For session IDs, request IDs, and anything not used as a sorted primary key, v4 is still a perfectly current choice.
A UUID is always 128 bits (16 bytes). Its canonical text form is 36 characters: 32 hexadecimal digits in an 8-4-4-4-12 pattern separated by four hyphens. Without hyphens it is 32 characters, and databases with a native uuid type (like PostgreSQL) store the raw 16 bytes — half the size of storing the text in a varchar(36).

