UUID Guide: Versions, Formats, and Best Practices
UUIDs (Universally Unique Identifiers) are 128-bit identifiers designed to be unique across space and time without a central authority. They are the standard choice for distributed systems where generating IDs independently β without coordination β is essential.
UUID Format
A UUID is a 128-bit number displayed as 32 hexadecimal digits in five groups separated by hyphens:
550e8400-e29b-41d4-a716-446655440000
^^^^^^^^ ^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^
time-low mid hi clk node
+ver +var
- Total: 128 bits (16 bytes)
- String length: 36 characters (32 hex + 4 hyphens)
- Version: Encoded in the 13th character (the "hi" nibble)
- Variant: Encoded in the 17th character
Generate UUIDs instantly with our UUID Generator.
UUID Versions
UUID v1: Time-Based
Generated from the current timestamp and the machine's MAC address.
// Structure: timestamp (60 bits) + clock sequence (14 bits) + node (48 bits)
6ba7b810-9dad-11d1-80b4-00c04fd430c8
Pros: Naturally sortable by creation time, guaranteed uniqueness per machine. Cons: Exposes MAC address (privacy concern), can reveal creation time. Use when: You need time ordering and are in a controlled environment.
UUID v4: Random
Generated from cryptographically secure random numbers. This is the most widely used version.
// 122 random bits (6 bits reserved for version and variant)
f47ac10b-58cc-4372-a567-0e02b2c3d479
Pros: Simple, no information leakage, no coordination needed. Cons: Not sortable, slightly worse database index performance than sequential IDs. Use when: General purpose β this is the default choice for most applications.
UUID v7: Time-Ordered Random (New Standard)
The newest version (RFC 9562, 2024), combining a Unix timestamp with random data.
// Structure: timestamp (48 bits) + random (74 bits)
018e7b50-4a00-7000-8000-000000000001
Pros: Naturally time-sorted, excellent database index performance, no information leakage beyond millisecond precision. Cons: Newer, some libraries may not support it yet. Use when: You need unique IDs that sort chronologically β ideal for database primary keys.
Other Versions
- UUID v3: MD5 hash of a namespace and name. Deterministic.
- UUID v5: SHA-1 hash of a namespace and name. Deterministic and preferred over v3.
- UUID v6: Reordered v1 for better sortability. Superseded by v7.
- Nil UUID: All zeros (
00000000-0000-0000-0000-000000000000). Used as a sentinel value.
Collision Probability
How likely are two randomly generated UUIDs (v4) to collide? With 122 random bits:
- After generating 1 billion UUIDs: probability β 1 in 10^18
- To have a 50% chance of collision: you need approximately 2.7 Γ 10^18 UUIDs
- At 1 billion UUIDs per second: it would take about 86 years
For all practical purposes, UUID v4 collisions will not happen. You are far more likely to experience a hardware failure.
UUID vs Other ID Formats
| Format | Length | Sortable | Unique | URL-Safe |
|---|---|---|---|---|
| UUID v4 | 36 chars | No | Yes | Yes |
| UUID v7 | 36 chars | Yes | Yes | Yes |
| ULID | 26 chars | Yes | Yes | Yes |
| nanoid | 21 chars | No | Probably | Yes |
| Auto-increment | Variable | Yes | Per-table | Yes |
| Snowflake ID | 18-19 chars | Yes | Per-system | Yes |
ULID (Universally Unique Lexicographically Sortable Identifier)
ULIDs are a compact alternative: 48-bit timestamp + 80-bit random, encoded as 26 Crockford Base32 characters. They sort lexicographically by creation time.
When to Use Auto-Increment IDs
Sequential IDs are simpler and more efficient for single-database applications. Use UUIDs when you need:
- IDs generated by multiple systems independently
- IDs that don't reveal insertion order to external users
- Merge-friendly IDs for distributed databases
Database Performance Considerations
Random UUIDs (v4) cause B-tree index fragmentation because inserts happen at random positions. This can degrade write performance by 2-5x compared to sequential IDs on large tables.
Solutions:
- Use UUID v7: Time-ordered UUIDs insert sequentially, matching auto-increment performance
- Store as binary: Use
BINARY(16)instead ofCHAR(36)to save 55% storage - Use ULID: Sortable and more compact than UUIDs
-- PostgreSQL: native UUID type (16 bytes, efficient)
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL
);
-- MySQL: store as BINARY(16) for performance
CREATE TABLE users (
id BINARY(16) PRIMARY KEY,
name VARCHAR(255) NOT NULL
);
Generating UUIDs
Command Line
# macOS/Linux
uuidgen
# Python one-liner
python3 -c "import uuid; print(uuid.uuid4())"
JavaScript
// Built-in (Node.js 19+, modern browsers)
crypto.randomUUID();
// For UUID v7 (using uuid package)
import { v7 } from 'uuid';
const id = v7();
Python
import uuid
uuid.uuid4() # Random
uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com') # Name-based
For quick generation without code, our UUID Generator creates v4 UUIDs instantly in your browser.
FAQ
Should I use UUID or auto-increment integer for my database primary key?
For single-database applications, auto-increment integers are simpler and faster. For distributed systems, microservices, or when you need to generate IDs client-side before database insertion, UUIDs (preferably v7) are the better choice. If you are using PostgreSQL, native UUID support makes the performance difference negligible.
Can UUIDs be used as security tokens?
UUID v4 uses 122 bits of randomness from a cryptographic source, which provides good entropy. However, for security tokens (API keys, session IDs), it is better to use purpose-built token formats with additional properties like checksums, expiration encoding, or prefix identification. UUIDs are for identity, not authentication.
Related Resources
- UUID Generator β Generate UUIDs instantly online
- Hash Algorithms Compared β Understanding the hash functions behind UUID v3 and v5
- JSON API Design Patterns β Using UUIDs effectively in API responses