A random UUID (v4) is a 128-bit identifier like 550e8400-e29b-41d4-a716-446655440000 — 32 hexadecimal characters plus four hyphens (36 chars total) — where 122 bits are random and 6 bits are fixed to mark it as version 4. It requires no central registry, is globally unique without coordination, and is the default choice for database keys, session IDs, and distributed systems. Generating one correctly means using a cryptographically secure random source, not Math.random().
This A-to-Z guide explains what a UUID v4 is, how its 128 bits are structured, how it compares to v1, v5, and the new v7, how to generate a random UUID v4 online and in 6 languages, when to use it (and when to choose v7 instead), collision math, storage best practices, and the pitfalls that cause duplicates or insecure IDs — with references to RFC 4122 and its 2024 successor RFC 9562.
4 and the 19th char 8, 9, a, or b — e.g., 550e8400-e29b-41d4-a716-446655440000. Generate one instantly with a random UUID generator (one or bulk, with format options) or in code with crypto.randomUUID() (JS), uuid.uuid4() (Python), UUID.randomUUID() (Java), or uuidgen (terminal) — all using a CSPRNG.
What Is a UUID and What Is UUID v4?
UUID (Universally Unique Identifier), also called GUID, is a 128-bit label standardized in RFC 4122 and updated by RFC 9562 (2024), which adds v6, v7, v8 and the Max UUID. The canonical text form is 36 characters: 32 hexadecimal digits in five groups 8-4-4-4-12 separated by hyphens, e.g., 550e8400-e29b-41d4-a716-446655440000. Without hyphens it is 32 chars; as raw bytes it is 16 bytes.
UUID v4 is the random variant — 122 of the 128 bits are generated from a cryptographically secure pseudorandom number generator (CSPRNG), and 6 bits are fixed: the version nibble (13th hex char) is 4 and the variant nibble (19th hex char) is 8, 9, a, or b (binary 10xx for the RFC variant). Per RFC 4122 §4.4, this makes v4 globally unique without any central coordination, unlike v1 which embeds time and MAC address.
Think of v4 as a random 122-bit number dressed as a 36-character string — 2122 ≈ 5.3×1036 possibilities. Generating one billion per second for 85 years is needed for a 50% chance of a single collision (birthday paradox), making collisions practically impossible for any real application. This property is why v4 is the default for distributed primary keys, session IDs, and idempotency keys.
Anatomy of a UUID v4 — 128 Bits, 36 Characters
The string 550e8400-e29b-41d4-a716-446655440000 breaks down as:
| Group | Chars | Bits | Meaning |
|---|---|---|---|
550e8400 | 8 | 32 | time_low (random in v4) |
e29b | 4 | 16 | time_mid (random) |
41d4 | 4 (first char is 4) | 16 (12 random + 4 version) | time_hi_and_version — version nibble = 4 |
a716 | 4 (first char 8/9/a/b) | 16 (14 random + 2 variant) | clock_seq — variant 10xx = RFC |
446655440000 | 12 | 48 | node (random in v4) |
Pattern: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx where 4 is fixed and y is 8, 9, a, or b. Total: 32 hex chars + 4 hyphens = 36 chars; 122 random bits + 6 fixed = 128 bits. Without hyphens: 32 chars; as bytes: 16 bytes. Case is conventionally lowercase per Wikipedia: UUID and MDN: crypto.randomUUID().
Nil and max: RFC 9562 defines 00000000-0000-0000-0000-000000000000 (Nil) and ffffffff-ffff-ffff-ffff-ffffffffffff (Max) — not random, reserved.
UUID Versions Compared — v1 vs v4 vs v5 vs v7
| Version | How It's Made | Example | When to Use |
|---|---|---|---|
| v1 | Time + MAC address | 6ba7b810-9dad-11d1-80b4-00c04fd430c8 | Legacy — leaks MAC and time; avoid for privacy |
| v4 ★ | 122 random bits (CSPRNG) | 550e8400-e29b-41d4-a716-446655440000 | Default — distributed IDs, keys, tokens |
| v5 | SHA-1 hash of namespace + name | 886313e1-3b8a-5372-9b90-0c9aee199e5d | Deterministic — same input → same UUID (e.g., UUID for "user:123") |
| v7 (2024) | Unix ms timestamp + random | 017f22e2-79b0-7cc3-98c4-72e20c45dced | Time-ordered, DB-friendly — best for primary keys at scale |
Why v4 is the default: No coordination, no leakage, no sorting by creation time — just random and unique. Use v4 when a random, unique ID is needed without central sequencing.
- Choose v7 when: IDs need to be time-ordered for better B-tree index locality. At high write rates, random v4 fragments indexes and slows inserts; v7's timestamp prefix keeps recent rows together. RFC 9562 positions v7 as the new time-ordered standard, replacing v1 without privacy leakage.
- Choose v5 when: Determinism is needed — e.g., the UUID for
"user:123"must always be the same across services without storing a mapping. - Avoid v1 for privacy: It embeds the host's MAC address and timestamp, leaking host identity and creation time.
How to Generate a Random UUID v4 Online (Easiest)
- Open the generator: The tool works in the browser with no signup and handles bulk generation — 1, 10, 50, or 100 at a time — plus format options.
- Generate and choose format: Click Generate for a new UUID. Options include lowercase (default, per RFC), uppercase, no hyphens (32-char compact), braces (
{uuid}for Microsoft-style), and URN (urn:uuid:uuid). The generator usescrypto.getRandomValues()— the browser's CSPRNG — so the 122 bits are cryptographically random. - Copy as needed: Copy a single UUID, a list, JSON array, or CSV — ready for SQL inserts, API tests, or seeding a database. Bulk generation is browser-side, so even 100 UUIDs never leave the device.
What to verify: The 13th character is 4 and the 19th is 8, 9, a, or b — a quick visual check that the output is a valid v4 per RFC 4122 §4.4.
How to Generate UUID v4 in Code — 6 Ways (Copy-Paste)
All of these use a CSPRNG under the hood — never Math.random(), which is predictable and must not be used for IDs that need uniqueness or unpredictability.
1. JavaScript (Browser and Node 19+)
// Browser and Node 19+ — built-in, no library
crypto.randomUUID()
// → "550e8400-e29b-41d4-a716-446655440000"
// Older Node or custom: uuid npm
import { v4 as uuidv4 } from 'uuid';
uuidv4()
Per MDN: crypto.randomUUID(), this is the standard since 2021 — synchronous, CSPRNG-backed, and available in all modern browsers and Node.
2. Python
import uuid
uuid.uuid4() # UUID('550e8400-e29b-41d4-a716-446655440000')
str(uuid.uuid4()) # '550e8400-e29b-41d4-a716-446655440000'
uuid.uuid4().hex # '550e8400e29b41d4a716446655440000' (no hyphens)
The Python uuid docs note that uuid4() uses os.urandom() — the OS CSPRNG.
3. Terminal (Linux, macOS, Windows)
# Linux / macOS
uuidgen # 550E8400-E29B-41D4-A716-446655440000 (uppercase)
cat /proc/sys/kernel/random/uuid # lowercase on Linux
# Windows PowerShell
[guid]::NewGuid() # Guid
# Windows CMD
powershell -command "[guid]::NewGuid()"
4. Java, C#, Go
// Java
UUID.randomUUID() // java.util.UUID
// C#
Guid.NewGuid() // System.Guid
// Go (google/uuid)
import "github.com/google/uuid"
uuid.NewString() // "550e8400-e29b-41d4-a716-446655440000"
5. SQL (Database-Generated)
-- PostgreSQL (pgcrypto)
SELECT gen_random_uuid(); -- 550e8400-e29b-41d4-a716-446655440000
-- As default:
ALTER TABLE users ALTER COLUMN id SET DEFAULT gen_random_uuid();
-- MySQL
SELECT UUID(); -- includes dashes
-- SQLite
SELECT lower(hex(randomblob(4))) || '-' || ... -- or use extension
Generating in the database with gen_random_uuid() as a column default ensures every insert gets a valid v4 without application code.
6. Bulk Generation
For seeding, testing, or CSV import, generate 100-1000 at once via the online bulk mode or a loop:
# Python bulk
[uuid.uuid4() for _ in range(1000)]
# JS bulk
Array.from({length: 100}, () => crypto.randomUUID())
Where to Use UUID v4 — And When Not To
Use For
- Distributed primary keys: Multiple services can create IDs without a central sequence — no coordination, no single point of failure. This is why DynamoDB, Cassandra, and many microservices default to v4.
- Session IDs and API keys (with caveats): v4 is random enough for session identifiers when generated with a CSPRNG, but pair it with expiry and rotation — a UUID is not a secret by itself.
- File names for uploads:
550e8400-e29b-41d4-a716-446655440000.jpgis globally unique without checking for collisions. - Idempotency keys: Exactly-once processing — the client sends a v4, the server stores it, and retries with the same key are deduplicated.
- Tracing and correlation IDs: Propagate a v4 across services to stitch logs for one request.
Avoid For
- Sequential IDs: If the next ID must be larger than the last, use v7 or an auto-increment — v4 is random and not ordered.
- Short, human-memorable codes: For invite codes or short URLs, use Nano ID or similar — 36-character UUID is verbose for humans.
- Security tokens alone: A UUID is guessable at 122 bits but is not encryption — add expiry, scope, and signing (JWT) for auth tokens.
- High-write DB primary keys at scale: Random v4 fragments B-tree indexes, causing slower inserts and bloat at millions of rows. For write-heavy tables, v7's time-ordered prefix keeps recent rows together and is the 2024+ recommendation per RFC 9562.
- Sorting by creation time: v4 has no timestamp; sort requires a separate
created_atcolumn or v7.
Collision Math — Why Duplicates Don't Happen
With 122 random bits, there are 2122 ≈ 5.3×1036 possibilities. The birthday paradox gives:
- Generating 1 billion UUIDs per second for 85 years → 50% chance of one collision
- For 231 ≈ 2.1 billion IDs, the collision probability is ~1 in 261 — negligible
- For any application generating millions per day, the chance is effectively zero
This assumes a proper CSPRNG — Math.random() has far less entropy and must not be used.
Best Practices for Production (With Extra Detail)
Store Correctly
- PostgreSQL: Use the native
uuidtype (16 bytes, indexed efficiently) — notchar(36)text (36 bytes) and nottext. Per PostgreSQL uuid docs, the type validates format and is smaller and faster. - MySQL:
BINARY(16)withUUID_TO_BIN()/BIN_TO_UUID()is 16 bytes;CHAR(36)is 36 bytes. The binary form is more efficient for large tables. - Application: Treat UUID as an opaque string — don't parse the version/variant bits for business logic; they are for validation only.
Bulk and Format Options
- Bulk: Generate 1, 10, 50, or 100 at once for seeding or CSV import — copy as a plain list, JSON array, or CSV column.
- Case: Lowercase is conventional per RFC 4122 §3; uppercase is accepted but lower is expected by most tools and MDN examples.
- Hyphens: Standard is hyphenated
8-4-4-4-12; some systems want 32-char compact (no hyphens) —uuid.hexin Python. The generator offers both. - Braces and URN: Microsoft-style
{uuid}andurn:uuid:uuidfor Windows/GUID interop.
Database Index Fragmentation (Extra Info)
Random v4 causes B-tree index fragmentation because new rows land at random pages rather than the end, increasing write amplification and index size at scale (millions of inserts/day). For write-heavy tables (events, logs), prefer v7 — its millisecond timestamp prefix makes inserts roughly sequential while retaining uniqueness. For read-heavy or moderate-write tables, v4's fragmentation is negligible and the simplicity wins. Measure with pgstattuple if concerned.
Security and Randomness (Extra Info)
UUID v4 is not a secret — it is random but not encrypted, and 122 bits is guessable only at astronomical cost but is still enumerable in theory. For session IDs, pair with HttpOnly, Secure, SameSite cookies, expiry, and rotation. Crucially, use a CSPRNG: crypto.getRandomValues() / crypto.randomUUID() / os.urandom() / /dev/urandom — not Math.random(), which is a PRNG with ~52 bits and predictable seeding. The online tool uses crypto.getRandomValues() browser-side, so the 122 bits never leave the device and are not generated server-side.
How to Validate a UUID v4
A valid v4 matches the pattern ^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ (lowercase; add i flag for case-insensitive). The 4 after the second hyphen and the [89ab] after the third are the version and variant checks. Any string failing this is not a valid v4 — e.g., 550e8400-e29b-41d4-c716-... fails because the variant is c (must be 8/9/a/b).
For bulk validation, paste a list into a validator to flag non-v4 lines before import.
UUID v4 vs Alternatives — Extended Comparison (Extra Info)
| ID Type | Bits / Chars | Ordered? | Best For |
|---|---|---|---|
| UUID v4 | 122 random / 36 chars | No | General random IDs, distributed keys |
| UUID v7 | 74 time + 74 random / 36 chars | Yes (time) | High-write DB primary keys (2024+) |
| Nano ID | ~126 bits / 21 chars (base64) | No | Short, URL-friendly, human-shareable |
| Snowflake ID | 64 bits / 19 digits | Yes | Twitter-style distributed sequence (needs worker ID) |
| Auto-increment | 32-64 bits / variable | Yes | Single DB, simple, reveals count |
If the IDs are user-visible and short is important, Nano ID's 21 characters beat UUID's 36. If ordering for DB indexes matters, v7 beats v4. If no coordination and no ordering need, v4 is the simplest and most widely supported.
FAQs About Generating Random UUIDs (A to Z)
How do I generate a random UUID v4 online?
Open a random UUID generator, click Generate for a new 36-character v4 (e.g., 550e8400-e29b-41d4-a716-446655440000), and copy. Use bulk mode for 10-100 at once, and choose lowercase, no-hyphens, or braces as needed. The generation uses crypto.getRandomValues() browser-side.
What is the difference between UUID v4 and v7?
v4 is 122 random bits — fully random, not time-ordered, best for general IDs. v7 is Unix millisecond timestamp plus random — time-ordered, better for database index locality at high write rates, and the 2024 RFC 9562 recommendation for new time-ordered IDs.
Is UUID v4 secure and unique enough for primary keys?
Yes for uniqueness — 2122 possibilities make collisions effectively impossible. For security, it is random but not secret — use it as an identifier, not as a password. Pair session IDs with expiry and CSPRNG generation.
Can UUID v4 collide? What is the collision probability?
Theoretically yes, practically no. At 1 billion per second for 85 years, the chance of one collision is ~50% (birthday paradox). For 2.1 billion IDs, the chance is ~1 in 261. For normal app volumes, the risk is negligible.
How do I generate UUID v4 in JavaScript and Python?
JavaScript: crypto.randomUUID() (browser and Node 19+). Python: import uuid; uuid.uuid4(). Both use the OS CSPRNG and produce lowercase hyphenated v4.
Should I store UUID as text or binary in the database?
Store as native uuid (PostgreSQL, 16 bytes) or BINARY(16) (MySQL) — half the size of CHAR(36) text and faster to index. Use char(36) only for human-readable exports.
Why is my UUID not version 4?
Check the 13th character — it must be 4 for v4, and the 19th must be 8, 9, a, or b. Strings with other values are v1, v5, or invalid. Validate with ^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$.
Conclusion
A random UUID v4 is a 122-bit random number with 6 fixed bits — 36 characters, globally unique without coordination, and the default for distributed systems. Whether generated online in bulk or in code with crypto.randomUUID() or uuid.uuid4(), the requirements are the same: a CSPRNG, lowercase hyphenated form, and storage as 16 bytes in the database for efficiency. For high-write, time-ordered needs, evaluate v7; for everything else, v4 remains the simplest correct choice.
Generate the next UUID — single or bulk — with a browser-side random UUID generator and copy the format needed for the database, API, or file name.