Every database needs a way to uniquely identify records. Every distributed system needs collision-free identifiers. UUIDs (Universally Unique Identifiers) solve this problem elegantly — generating identifiers so unique that you can create them independently on millions of machines without coordination, and they'll never collide.
This guide explains what UUIDs are, how they work, the key UUID v4 vs v7 differences, and when to use each version in your projects.
What Is a UUID?
A UUID is a 128-bit number used to uniquely identify information. It's formatted as 32 hexadecimal digits displayed in 5 groups separated by hyphens:
550e8400-e29b-41d4-a716-446655440000
The format: xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
Where:
- M indicates the UUID version (1-5, 7)
- N indicates the variant (usually 8, 9, a, or b for RFC 4122)
UUID vs GUID
UUID (Universally Unique Identifier) is the standard term defined by RFC 4122.
GUID (Globally Unique Identifier) is Microsoft's term for the same concept.
They are functionally identical. The only differences are cultural:
- UUID: Used in most programming languages, Linux, databases, web standards
- GUID: Used in Microsoft .NET, Windows, SQL Server, COM/DCOM
If someone asks for a GUID, give them a UUID. They're the same thing.
How Unique Are UUIDs?
The total number of possible UUIDs is 2¹²⁸ = approximately 340 undecillion (3.4 × 10³⁸).
To put this in perspective:
- If you generated 1 billion UUIDs per second, it would take 10 billion years to exhaust the space
- The probability of generating two identical random UUIDs is astronomically low
- You'd need approximately 2.71 quintillion UUIDs before a 50% probability of collision
For all practical purposes, UUIDs are unique without any central coordination.
UUID Versions
UUID v1 (Timestamp + MAC Address)
Combines a timestamp with the device's MAC address.
Example: 6fa459ea-ee8a-11e7-80c1-9a214cf093ae
How it works: Uses the current timestamp (100-nanosecond intervals since October 15, 1582) and the network card's MAC address.
Advantages:
- Naturally sortable by creation time
- Guaranteed unique on a single machine
Disadvantages:
- Leaks information: Reveals the MAC address and creation time
- Privacy concern: Can be traced back to the generating machine
- Not recommended for public-facing systems
UUID v4 (Random)
Generated entirely from random numbers. The most commonly used version.
Example: 550e8400-e29b-41d4-a716-446655440000
How it works: 122 random bits (6 bits are used for version and variant).
Advantages:
- No information leakage
- Simple to implement
- No dependencies on hardware or time
- Most widely supported
Disadvantages:
- Not sortable by creation time
- Poor database index performance (random distribution)
- Requires a good random number generator
UUID v5 (Name-Based, SHA-1)
Deterministic — the same input always produces the same UUID.
UUID v5 for "example.com" in DNS namespace:
cfbff0d1-9375-5685-968c-48ce8b15ae17
How it works: Combines a namespace UUID with a name string and hashes with SHA-1 (you can explore how hashing works with our Hash Generator).
Advantages:
- Deterministic — same input = same output
- Good for generating consistent IDs from known data
- No information leakage beyond the hash
Disadvantages:
- SHA-1 has known weaknesses (though collision attacks aren't practical for UUIDs)
- Requires choosing a namespace
Use case: Generating consistent IDs for URLs, domains, or other named entities.
UUID v7 (Timestamp-Ordered, Random) — The Modern Choice
The newest version, designed to address v4's database performance issues.
Example: 018f3e9c-5b3a-7d4e-8a1b-2c3d4e5f6a7b
How it works: Combines a Unix timestamp (millisecond precision) with random data.
Advantages:
- Time-ordered: Sortable by creation time
- Database-friendly: Sequential IDs create efficient B-tree indexes
- No information leakage: Unlike v1, doesn't reveal hardware addresses
- Best of both worlds: Combines v1's sortability with v4's privacy
Disadvantages:
- Newer — less widespread library support (but growing fast)
Recommendation: Use UUID v7 for new projects when your language/framework supports it. Fall back to v4 otherwise.
UUID in Databases
UUID vs Auto-Increment IDs
| Feature | UUID | Auto-Increment |
|---|---|---|
| Uniqueness scope | Global | Single table |
| Generation | Anywhere, independently | Database only |
| Predictability | Unpredictable (v4) | Sequential, predictable |
| Size | 16 bytes (128 bits) | 4-8 bytes (32-64 bits) |
| Index performance | Poor (v4), Good (v7) | Excellent |
| Merge-friendly | Yes | No (conflicts likely) |
| Information leakage | None (v4/v7) | Reveals row count |
When to Use UUIDs
- Distributed systems: Multiple databases generating IDs independently
- API resources: Public-facing IDs that shouldn't reveal row counts (inspect UUID-containing API responses with a JSON formatter)
- Microservices: Services creating records independently
- Offline-first apps: Generate IDs before syncing to server
- Data merge scenarios: Combining data from multiple sources
When to Use Auto-Increment
- Simple applications: Single database, no distributed requirements
- Performance-critical: When index performance matters most
- Internal IDs: Non-public identifiers where predictability doesn't matter
- Legacy systems: When changing ID strategy isn't worth the effort
Storage Considerations
Store UUIDs efficiently in your database:
MySQL: Use BINARY(16) instead of CHAR(36) — saves 20 bytes per row
CREATE TABLE users (
id BINARY(16) PRIMARY KEY DEFAULT (UUID_TO_BIN(UUID(), 1)),
name VARCHAR(255)
);
PostgreSQL: Native UUID type (stored as 16 bytes)
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255)
);
Generating UUIDs
JavaScript
// Built-in (modern browsers and Node.js 19.0+)
crypto.randomUUID();
// "36b8f84d-df4e-4d49-b662-bcde71a8764f"
// Using uuid library (Node.js)
import { v4 as uuidv4 } from 'uuid';
uuidv4();
Python
import uuid
uuid.uuid4() # Random
# UUID('cd26ef66-9df2-4f3a-a2d7-123456789abc')
uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com') # Name-based
Command Line
# Linux
uuidgen
# macOS
uuidgen | tr '[:upper:]' '[:lower:]'
# Python one-liner
python3 -c "import uuid; print(uuid.uuid4())"
Common Mistakes
Using UUIDs as Passwords or Tokens
UUIDs are identifiers, not secrets. While v4 UUIDs are random, they're not designed for security. Use proper cryptographic token generators for authentication tokens and API keys — for strong passwords, try a dedicated password generator.
String Comparison Issues
UUID string comparisons are case-insensitive. These are the same UUID:
550e8400-e29b-41d4-a716-446655440000
550E8400-E29B-41D4-A716-446655440000
Always normalize to lowercase before comparing.
Storing as Strings
Storing UUIDs as CHAR(36) wastes space. Use native UUID types or BINARY(16) when available.
Exposing Sequential Information
UUID v1 reveals creation time and MAC address. Never use v1 for public-facing identifiers. Use v4 or v7 instead.
Conclusion
UUIDs are a simple solution to a complex problem — generating unique identifiers without coordination. The key decision is which version to use:
- UUID v4: The safe default — random, private, widely supported
- UUID v7: The modern choice — time-ordered, database-friendly, private
- UUID v5: When you need deterministic IDs from known data
- UUID v1: Only for internal systems where timestamp + MAC leakage is acceptable
For most applications, UUID v4 is the right choice. If database performance is a concern and your stack supports it, UUID v7 is the future.
Related Reading
- Password Security Guide — why UUIDs are not a substitute for secure tokens and how to handle secrets properly
- Client-Side Security Best Practices — protecting identifiers and sensitive data in browser-based applications
- Base64 Encoding Explained — another encoding concept frequently paired with UUIDs in API design
Need to generate UUIDs? Our UUID Generator creates v4 UUIDs instantly in your browser — generate singles or batches, copy with one click, all processed locally.