Skip to content
Browse tools

Identifiers guide ยท UUID & GUID

128 bits.
No central counter.
No collisions.

A UUID (Universally Unique Identifier) is a 128-bit value any machine can generate on its own, with no database round-trip and no coordination, and still be confident nobody else will ever generate the same one. This page explains the format, the versions, the real odds, and which one to pick for a database key. ๐Ÿ‘‡

โ–ธ a version 4 UUID
3f0f8c5a-7c22-4b1f-9f07-2f7f9a8c2041
๐ŸŒ
Decentralised
Make them anywhere

Browser, phone, server, offline โ€” no need to ask a database for the next number.

๐Ÿ”€
Mergeable
No clashes

Combine records from two systems without renumbering anything.

๐Ÿ™ˆ
Opaque
Not guessable

Unlike /orders/1042, a random ID doesn't reveal how many orders you have.

๐Ÿ“œ

The standard: UUIDs are defined by RFC 9562 (published 2024), which replaced the long-standing RFC 4122 and added versions 6, 7 and 8.

02 ยท Reading one

๐Ÿ” The 8-4-4-4-12 format

A UUID is 16 bytes. Its standard text form is 32 hexadecimal digits in five hyphen-separated groups of 8, 4, 4, 4 and 12 โ€” 36 characters in total. Two positions tell you what kind of UUID you're looking at:

PositionIn the exampleMeaning
First digit of the 3rd group4b1f โ†’ 4The version โ€” how it was generated (1โ€“8).
First digit of the 4th group9f07 โ†’ 9The variant. 8, 9, a or b means the standard RFC layout, which is almost everything you'll see.
Everything elseโ€”Random bits, a timestamp, or a hash, depending on the version.

๐Ÿชช UUID vs GUID

They're the same thing. GUID (Globally Unique Identifier) is Microsoft's name, used in Windows, COM, .NET and SQL Server. The differences are cosmetic:

  • Braces. Microsoft tools often show {3F0F8C5A-7C22-4B1F-9F07-2F7F9A8C2041}. The braces aren't part of the value.
  • Case. The RFC says to output lowercase and accept either case on input. Compare case-insensitively.
  • Byte order. .NET's Guid.ToByteArray() stores the first three groups little-endian, so its raw bytes differ from the RFC's order even though the string is identical. This only bites when you exchange binary UUIDs between platforms.
๐Ÿงท

Special values: the nil UUID is all zeros, 00000000-0000-0000-0000-000000000000, and is commonly used as "no value". RFC 9562 also defines a max UUID of all fs.

03 ยท Which kind

๐Ÿงฌ UUID versions compared

The version decides where the 128 bits come from. In practice you'll choose between v4, v7 and, occasionally, v5.

VersionBuilt fromSortable?Use it for
v1Timestamp (100 ns ticks since 1582) + clock sequence + node ID, traditionally the MAC addressNot by stringLegacy only. Leaks when and on which machine it was made.
v3MD5 hash of a namespace UUID + a nameNoLegacy deterministic IDs โ€” prefer v5.
v4122 random bitsNoDefault General-purpose unique IDs.
v5SHA-1 hash of a namespace UUID + a nameNoThe same input always gives the same UUID โ€” stable IDs for URLs, emails, external keys.
v6v1's fields reordered so time sorts firstYesMigrating v1 systems. New designs should use v7.
v748-bit Unix timestamp in milliseconds + 74 random bitsYesRecommended Database primary keys and anything you'll sort by creation time.
v8Vendor-defined layoutDependsCustom schemes that still want the UUID shape.

A v5 UUID for the DNS name quickdevelopertools.com is always 6a6e3815-b43b-593b-ab56-af1731b632b9, on every machine, forever โ€” handy when two systems need to derive the same ID from the same natural key without talking to each other.

04 ยท The honest maths

๐ŸŽฒ Will a v4 UUID ever collide?

A v4 UUID has 128 bits, but 6 are fixed (4 for the version, 2 for the variant), leaving 122 random bits โ€” about 5.3 ร— 1036 possible values.

The right way to think about collisions is the birthday problem: the question isn't whether a new ID matches one specific ID, it's whether any two IDs in your whole set match. That probability grows with the square of how many you've made. Even so:

โ‰ˆ 2.7 ร— 1018

UUIDs for a 50% chance

You'd need to generate roughly 2.7 quintillion v4 UUIDs before the odds of any duplicate reach a coin flip.

โ‰ˆ 86 years

at a billion per second

That's how long it takes to generate that many, producing one billion UUIDs every second without stopping.

For any realistic system โ€” even billions of rows โ€” the chance of a v4 collision is so small it's dwarfed by hardware faults and ordinary bugs. You can use v4 IDs without a uniqueness check in the application, though keeping a unique constraint in the database costs little and protects you from the failure mode that does happen:

โš ๏ธ

Real collisions come from bad randomness, not bad luck. A weak or badly seeded random generator โ€” cloned virtual machines, a fixed seed in tests, a non-cryptographic Math.random() implementation โ€” can produce duplicates far sooner than the maths suggests. Use your platform's built-in UUID function, which draws from a cryptographically secure source.

๐Ÿ”

Unique isn't the same as secret. The RFC advises against using UUIDs as security capabilities, and v1/v7 contain readable timestamps. For API keys, reset links and session tokens, generate a dedicated random token with the Token Generator.

05 ยท Primary keys

๐Ÿ—„๏ธ v7 for database keys & index locality

Random v4 keys have a performance cost in B-tree indexes โ€” the structure behind most primary keys. Each new row lands at a random spot in the index, so inserts touch pages all over it: more page splits, a larger working set that has to stay in memory, and a fragmented index over time.

v7 fixes that by putting the timestamp first. New IDs are always slightly larger than recent ones, so inserts cluster at the end of the index, much like an auto-increment integer โ€” while keeping the "generate anywhere" benefit.

โ–ธ v7 anatomy
019cebae-61c0-7a3c-9e41-5b8d0f2a6c17
โ””โ”€ timestamp โ”€โ”˜ โ”‚     โ”‚
   2026-03-14    โ”‚     โ”” variant
   09:30:00Z     โ”” version 7         the rest: random

๐Ÿ‘ v7 advantages

  • Index-friendly inserts
  • Roughly sorts by creation time
  • Still generated anywhere, no coordination

๐Ÿ‘€ Things to know

  • The creation time is readable from the ID
  • Ordering within the same millisecond depends on the generator
  • Still 16 bytes โ€” twice a bigint
๐Ÿชค

SQL Server gotcha: the uniqueidentifier type doesn't sort by byte order โ€” it compares the last group first. A v7 GUID stored there doesn't get the locality benefit, because its timestamp is at the front. SQL Server's own answer is NEWSEQUENTIALID() as a column default; PostgreSQL's uuid type and MySQL's BINARY(16) compare bytes in order and do benefit from v7.

๐Ÿ’ก Store UUIDs in a native uuid / uniqueidentifier column or as 16 bytes of binary โ€” not as a 36-character string, which more than doubles the size of every index that includes it.

06 ยท In your code

๐Ÿ› ๏ธ Generating UUIDs

โ–ธ JavaScript
crypto.randomUUID();   // v4 โ€” browsers (secure contexts, i.e. HTTPS) and Node.js
โ–ธ C# / .NET
Guid id   = Guid.NewGuid();           // v4
Guid v7   = Guid.CreateVersion7();    // v7 โ€” .NET 9 and later
string s  = id.ToString();            // "3f0f8c5a-7c22-4b1f-9f07-2f7f9a8c2041"
string n  = id.ToString("N");         // no hyphens
bool ok   = Guid.TryParse(input, out var parsed);
โ–ธ Python
import uuid

uuid.uuid4()                                          # v4
uuid.uuid5(uuid.NAMESPACE_DNS, "quickdevelopertools.com")  # v5
uuid.uuid7()                                          # v7 โ€” Python 3.14+
โ–ธ SQL & terminal
-- PostgreSQL
SELECT gen_random_uuid();   -- v4 (built in since PostgreSQL 13)
SELECT uuidv7();            -- v7 (PostgreSQL 18+)

-- SQL Server
SELECT NEWID();             -- random GUID

# Linux / macOS
uuidgen
โšก

Need a batch right now? The GUID / UUID Generator creates one or many identifiers in the browser, in the format you need. For secrets rather than identifiers, use the Token Generator.

๐Ÿ“Œ Version layouts follow RFC 9562. Collision figures are standard birthday-bound approximations for 122 random bits. Language and database version requirements reflect current releases โ€” check your runtime's docs before relying on v7 support.

What is a UUID?
7 min read