UUIDs (Universally Unique Identifiers) are 128-bit identifiers used everywhere — database primary keys, API request IDs, distributed systems, session tokens. This guide covers the different UUID versions, how they work, and when to pick each one.
What Is a UUID?
A UUID is a 128-bit number represented as 32 hexadecimal digits in five groups separated by hyphens:
550e8400-e29b-41d4-a716-446655440000
\_____/ \__/ \__/ \__/ \__________/
8 4 4 4 12
Total: 32 hex digits = 128 bitsThe third group's first digit indicates the version. In the example above, 4 in 41d4 means UUID v4. The fourth group's first digit indicates the variant (usually 8, 9, a, or b for RFC 4122 UUIDs).
UUID vs GUID
They're the same thing. Microsoft calls them GUIDs (Globally Unique Identifiers), everyone else calls them UUIDs. The format, generation algorithms, and RFC specification are identical. If you see a GUID in .NET or SQL Server, treat it as a UUID.
UUID Versions Explained
UUID v1 — Timestamp + MAC Address
Combines a 60-bit timestamp (100-nanosecond intervals since October 15, 1582) with the machine's MAC address. UUIDs generated on the same machine sort chronologically.
f47ac10b-58cc-1de5-97d0-0242ac120002
^
version 1
Pros: Naturally sortable by time, guaranteed unique per machine
Cons: Leaks MAC address (privacy concern), clock skew issuesUUID v4 — Random
The most commonly used version. 122 bits are randomly generated (6 bits reserved for version and variant). No timestamp, no MAC address, no coordination needed.
550e8400-e29b-41d4-a716-446655440000
^
version 4
122 random bits → 2^122 possible values
≈ 5.3 × 10^36 unique UUIDs
Collision probability:
• 1 billion UUIDs → ~0.00000000000000003% chance
• You'd need to generate 2.71 × 10^18 UUIDs for a 50% chanceFor most applications, v4 is the right choice. The collision probability is so low that it's effectively zero for any real-world use case.
UUID v7 — Timestamp + Random (Recommended)
The newest version (RFC 9562, 2024). Combines a 48-bit Unix timestamp (millisecond precision) with 74 random bits. This gives you the best of both worlds: natural sortability and privacy.
018f6b5e-c913-7a2b-8d1f-3c4e5f6a7b8c
^
version 7
First 48 bits: Unix timestamp (ms)
Remaining bits: Random
Pros: Sortable by creation time, no MAC address leak
Cons: Newer, not yet supported everywhereUUID v7 is the recommended choice for new projects, especially for database primary keys. The timestamp prefix means IDs sort chronologically, which is significantly better for database index performance than random v4 UUIDs.
UUID v5 — Namespace + Name (SHA-1 Hash)
Deterministic: the same namespace + name always produces the same UUID. Useful when you need a stable identifier derived from a known value.
// Same inputs always produce the same UUID:
namespace = "6ba7b810-9dad-11d1-80b4-00c04fd430c8" (URL namespace)
name = "https://devbolt.dev"
result = "a6e5e5c0-..." (always the same)
Use cases:
• Generating IDs from URLs, emails, or DNS names
• Deduplication — same input = same IDWhich Version Should You Use?
| Use Case | Version | Why |
|---|---|---|
| Database primary keys | v7 | Sortable, good index performance |
| General unique IDs | v4 | Simple, widely supported |
| Deterministic IDs from names | v5 | Same input = same UUID |
| Legacy systems | v1 | Only if required by existing code |
Generating UUIDs in Code
// Built-in (v4) — Node.js 14.17+ and all modern browsers
const id = crypto.randomUUID();
// "3b241101-e2bb-4d7a-8613-e4bfa8964d71"
// Using the uuid package (v4)
import { v4 as uuidv4 } from "uuid";
const id = uuidv4();
// Using the uuid package (v7)
import { v7 as uuidv7 } from "uuid";
const id = uuidv7();import uuid
# v4 (random)
id = uuid.uuid4()
# UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')
# v5 (namespace + name)
id = uuid.uuid5(uuid.NAMESPACE_URL, "https://devbolt.dev")
# v7 (Python 3.14+)
id = uuid.uuid7()import "github.com/google/uuid"
// v4
id := uuid.New()
// "f47ac10b-58cc-4372-a567-0e02b2c3d479"
// v7
id, _ := uuid.NewV7()
// From string
parsed, err := uuid.Parse("550e8400-e29b-41d4-a716-446655440000")-- v4 (built-in since PostgreSQL 13)
SELECT gen_random_uuid();
-- Use as primary key
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email TEXT NOT NULL
);# macOS / Linux
uuidgen
# 5A6A8C6B-3E7D-4A2F-9B1C-8D5E6F7A8B9C
# Python one-liner
python3 -c "import uuid; print(uuid.uuid4())"
# Node.js one-liner
node -e "console.log(crypto.randomUUID())"UUID vs Auto-Increment IDs
| Feature | UUID | Auto-Increment |
|---|---|---|
| Size | 16 bytes | 4–8 bytes |
| Distributed generation | No coordination needed | Requires central authority |
| Predictability | Not guessable | Sequential, easy to enumerate |
| Index performance | v7 good, v4 poor | Excellent |
| URL safety | Doesn't leak count | Reveals total records |
Auto-increment IDs leak information. If your user profile is at /users/42, attackers know you have at most 42 users and can enumerate all of them. UUIDs prevent this.
Common Mistakes
- Using v4 as a database primary key without considering performance. Random UUIDs fragment B-tree indexes because inserts land at random positions. Use v7 for sequential inserts, or store UUIDs as
BINARY(16)instead ofCHAR(36). - Treating UUIDs as secrets. UUIDs are unique but not necessarily unpredictable (v1 is predictable). Never use a UUID as a password, API key, or security token. Use
crypto.randomBytes()or a dedicated token generator instead. - Storing UUIDs as strings. A UUID string is 36 characters (with hyphens). Stored as
CHAR(36), that's 36 bytes. Stored as a native UUID type orBINARY(16), it's only 16 bytes — less than half the storage and much faster to index. - Case-sensitive comparison. UUIDs are case-insensitive.
550E8400...and550e8400...are the same UUID. Always normalize to lowercase before comparing or storing.
Running PostgreSQL with UUID primary keys?
DigitalOcean Managed Databases handle backups, failover, and scaling for PostgreSQL, MySQL, and Redis. Built-in gen_random_uuid() support with no server management.
Try It Yourself
Use our UUID Generator to generate v1, v4, and v7 UUIDs instantly in your browser. Need to verify a hash of your UUID? Try the Hash Generator. And if you're building an API that uses UUIDs, check out the JSON Formatter to validate your API responses.