What Is a UUID and When Should You Use One?
Unique Identification in Distributed Systems
In software engineering, uniquely identifying database records is a fundamental task. Historically, developers relied on auto-incrementing integer keys (e.g. 1, 2, 3). This approach works well for simple applications with a single SQL database.
However, in modern web development, applications often run on distributed architectures with microservices, replicated databases, and client-side offline syncing. In these environments, auto-incrementing integers create significant issues:
- ID Collisions: If two independent database shards insert a record at the same time, they will generate the same ID.
- Security Risks: Auto-incrementing IDs make it easy for attackers to harvest data. If an account page is located at
/users/102, they can simply change the URL to/users/103to target other accounts. - Synchronization Conflicts: Devices creating records offline cannot assign IDs without first checking with a central server.
- Cross-Service Conflicts: In microservices architectures, multiple services generating IDs independently will inevitably create duplicates.
To solve these challenges, developers use UUIDs (Universally Unique Identifiers). In this article, we will examine the structure of UUIDs, compare versions, analyze collision math, and outline when to use them.
What is a UUID?
A UUID is a 128-bit value designed to be globally unique. Unlike sequential numbers, a UUID can be generated locally on any device without coordinating with a central authority, with a collision chance that is practically zero.
UUIDs are represented as 36-character hexadecimal strings split into five blocks by hyphens:
f81d4fae-7dec-11d0-a765-00a0c91e6bf6
This structure translates to:
- 8 hex characters (time-low)
- 4 hex characters (time-mid)
- 4 hex characters (time-high-and-version)
- 4 hex characters (clock-seq-and-reserved)
- 12 hex characters (node)
The 128-bit value provides $2^{128} \approx 3.4 \times 10^{38}$ possible combinations, which is more than enough to prevent duplicates. You can generate UUIDs locally using our client-side UUID Generator.
Understanding the UUID Versions
The UUID specification (RFC 9562) defines several versions, each using a different generation mechanism:
Version 1 (Time-Based)
Generates IDs using the device’s MAC address and system timestamp. This guarantees uniqueness but leaks the host device’s identity and creation time, raising privacy concerns.
Structure: Timestamp (60 bits) + Clock Sequence (14 bits) + MAC Address (48 bits)
Use case: Distributed databases where time ordering is important and privacy is not a concern.
Version 2 (DCE Security)
Based on Version 1 but replaces part of the timestamp with a local identifier (like a user ID or group ID). Rarely used in modern applications.
Version 3 (Name-Based, MD5)
Generates IDs by hashing a namespace identifier and a text string using MD5. The output is deterministic: the same input will always produce the same UUID.
Structure: MD5(namespace + name) with version and variant bits set
Use case: Generating deterministic IDs from human-readable names, where you need the same UUID every time for the same input.
Version 4 (Random-Based)
Generates IDs using fully random values (or pseudo-random values). It is the most common version used in modern web applications. Out of the 128 bits, 6 bits are reserved for metadata, leaving 122 bits of random entropy.
Structure: 122 random bits + 6 version/variant bits
Use case: General-purpose unique identifiers where time ordering is not required.
Version 5 (Name-Based, SHA-1)
Similar to Version 3 but uses SHA-1 instead of MD5. Provides better collision resistance than Version 3.
Structure: SHA-1(namespace + name) with version and variant bits set
Use case: Deterministic UUID generation where stronger hash security is needed.
Version 6 (Reordered Time-Based)
A reordering of Version 1 that places the timestamp in the most significant bits, making UUIDs sortable in lexicographic order. This improves database index performance.
Structure: Reordered timestamp (60 bits) + Clock Sequence (14 bits) + MAC Address (48 bits)
Use case: Distributed databases where both time ordering and database performance are critical.
Version 7 (Time-Ordered Random)
A newer standard that combines a Unix millisecond timestamp with random bits. This creates sequentially ordered IDs, which improves database index insertion performance.
Structure: Unix timestamp in ms (48 bits) + Random bits (74 bits) + Version/Variant (6 bits)
Use case: High-performance databases where sequential insertion order matters.
Version 8 (Custom)
Reserved for application-specific UUIDs. The 128 bits can be used for any custom purpose while maintaining UUID format compatibility.
Version Comparison Table
| Version | Generation Method | Entropy Bits | Sortable | Privacy | Use Case |
|---|---|---|---|---|---|
| V1 | Timestamp + MAC | 60 | Time-ordered | Low (leaks MAC) | Legacy distributed systems |
| V3 | MD5 hash | 122 | No | High | Deterministic name-based |
| V4 | Random | 122 | No | High | General-purpose |
| V5 | SHA-1 hash | 122 | No | High | Deterministic (secure) |
| V6 | Reordered V1 | 60 | Lexicographic | Low | Ordered distributed DBs |
| V7 | Timestamp + Random | 74 | Lexicographic | High | Modern ordered databases |
| V8 | Custom | 128 | Varies | Varies | Application-specific |
The Mathematics of UUID v4 Collisions
When using random UUIDs, developers often ask: What is the chance of a collision?
To calculate this probability, we use the Birthday Paradox, which shows that in a group of randomly selected people, the probability of two sharing a birthday is much higher than intuitive guesses suggest.
For UUID v4 (with 122 bits of random entropy), the number of IDs you must generate to have a 50% chance of a single collision is approximately: $$N \approx \sqrt{2 \times 2^{122}} \approx 2.7 \times 10^{18}$$
To put this in perspective: if you generate 1 billion UUIDs every second for 85 years, the chance of experiencing a single duplicate is about 50%. Generating a duplicate by accident is mathematically negligible.
Collision Probability Table
| UUIDs Generated | Collision Probability (V4) |
|---|---|
| 1 million | ~0.0000000000000000001% |
| 1 billion | ~0.00000000000000001% |
| 1 trillion | ~0.000000000000001% |
| 1 quadrillion | ~0.0000000000001% |
| $2.7 \times 10^{18}$ | ~50% |
UUID v7 Collision Analysis
UUID v7 has slightly less entropy than v4 (74 bits vs. 122 bits), but the timestamp component ensures that UUIDs generated at different times are unique. The collision risk only exists for UUIDs generated within the same millisecond on the same machine. With 74 random bits, you would need to generate approximately $1.9 \times 10^{11}$ UUIDs within the same millisecond to reach a 50% collision probability—practically impossible.
When to Use UUIDs
UUIDs are ideal for several scenarios:
1. Distributed Microservices
When independent services generate records that must merge into a central warehouse without conflicts. Each service can generate UUIDs locally without coordinating with other services or a central authority.
2. Client-Side Generation
Applications that allow users to create records offline (like note-taking apps) and sync them when they reconnect. UUIDs eliminate the need for server-assigned IDs during the initial creation.
3. Secure Resource Links
Using UUIDs in public URLs (e.g. /orders/3482a5a1-5d2f-4c5e-881c-0b82f09d84bf) to prevent ID enumeration attacks. Attackers cannot predict or iterate through UUIDs to access other users’ resources.
4. Session Tokens
Using random UUIDs as session identifiers. You can also generate secure random keys using our local Password Generator.
5. Database Sharding
When databases are sharded across multiple servers, UUIDs ensure that records created on different shards never have conflicting IDs. This is critical for eventual consistency architectures.
6. API Resource Identifiers
RESTful APIs often use UUIDs as resource identifiers to ensure globally unique references across different API versions and deployments.
When to Avoid UUIDs
While powerful, UUIDs have drawbacks:
1. Database Index Performance
Because UUID v4 is random, inserting records into indexed columns can cause B-Tree page fragmentation in databases like MySQL (InnoDB) or PostgreSQL. This degrades insert speeds by 30-50% compared to sequential integers. In these cases, using sequential identifiers or UUID v7 is recommended.
2. Storage Overhead
A UUID requires 16 bytes of storage as binary, or 36 bytes as a string. A standard integer requires only 4 bytes. In high-volume databases, this overhead can impact memory and disk utilization.
| ID Type | Storage Size | Index Size (per record) | 1M Records |
|---|---|---|---|
| Integer (INT) | 4 bytes | ~4 bytes | ~8 MB |
| BigInt | 8 bytes | ~8 bytes | ~16 MB |
| UUID (binary) | 16 bytes | ~16 bytes | ~32 MB |
| UUID (string) | 36 bytes | ~36 bytes | ~72 MB |
3. Readability
UUIDs are long and difficult for humans to read or communicate (e.g. when troubleshooting customer support tickets). If you need to serialize binary buffers into URL-safe formats, check out our Base64 Converter and URL Encoder/Decoder.
4. No Ordering Information
UUID v4 provides no information about when a record was created. If you need to sort records by creation time, you must store a separate timestamp column. UUID v7 addresses this by embedding a timestamp.
UUIDs vs. Other ID Strategies
| Strategy | Uniqueness | Sequential | Size | Offline Generation | Security |
|---|---|---|---|---|---|
| Auto-Increment | Single DB only | Yes | 4 bytes | No | Low (enumerable) |
| UUID v4 | Global | No | 16 bytes | Yes | High (random) |
| UUID v7 | Global | Yes | 16 bytes | Yes | High (random + time) |
| ULID | Global | Yes | 16 bytes | Yes | High |
| NanoID | Configurable | Optional | Variable | Yes | High |
| CUID2 | Global | Partial | Variable | Yes | High |
When to Choose UUID v7 Over v4
Choose UUID v7 when:
- You need time-ordered records without a separate timestamp column.
- Database insertion performance is critical.
- You want lexicographic sorting for free.
Choose UUID v4 when:
- You need maximum randomness and unpredictability.
- Time ordering is not important.
- You are generating UUIDs for session tokens or cryptographic purposes.
Practical Implementation Tips
Storing UUIDs Efficiently
Store UUIDs as binary (16 bytes) rather than strings (36 bytes) in your database. Most databases support native UUID types:
-- PostgreSQL
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255)
);
-- MySQL 8.0+
CREATE TABLE users (
id BINARY(16) PRIMARY KEY,
name VARCHAR(255)
);
Generating UUIDs in Code
JavaScript:
const uuid = crypto.randomUUID();
console.log(uuid); // "3b241101-e2bb-4d7a-8702-9e9e42b58b25"
Python:
import uuid
print(uuid.uuid4()) # "3b241101-e2bb-4d7a-8702-9e9e42b58b25"
Go:
import "github.com/google/uuid"
id := uuid.New()
fmt.Println(id.String())
Online Generation
You can generate UUIDs instantly using our browser-based UUID Generator. All generation happens client-side—no data is sent to any server.
Frequently Asked Questions
What is the difference between UUID v4 and v7?
UUID v4 generates 122 bits of pure randomness with no time ordering. UUID v7 combines a 48-bit Unix millisecond timestamp with 74 bits of randomness, creating time-ordered IDs that improve database insertion performance. Use v4 for maximum randomness, and v7 when time ordering matters.Can UUIDs be guessed by attackers?
UUID v4 has 122 bits of entropy, making it computationally infeasible to guess. However, UUID v1 leaks the MAC address and timestamp, which can be used to predict future UUIDs. For security-sensitive applications, use UUID v4, v5, or v7.Should I store UUIDs as strings or binary?
Store UUIDs as binary (16 bytes) for better performance and storage efficiency. Most databases support native UUID types that handle binary storage automatically. Only use string format for display purposes or API responses.What is the difference between UUID and ULID?
Both are 128-bit identifiers, but ULID (Universally Unique Lexicographically Sortable Identifier) uses a different encoding (Crockford's Base32) that is more URL-friendly and case-insensitive. UUID v7 and ULID serve similar purposes (time-ordered, collision-resistant), but ULID is simpler and more compact.When should I use NanoID instead of UUID?
NanoID is a URL-friendly unique string ID generator. Use it when you need shorter, more readable IDs (default 21 characters vs. UUID's 36). NanoID is popular for URL shorteners, invite codes, and user-facing identifiers where readability matters.Do I need UUIDs for a small single-database application?
Not necessarily. Auto-incrementing integers are simpler, faster, and more storage-efficient for single-database applications. However, if you plan to scale to multiple databases or need security against ID enumeration, UUIDs are worth the overhead.GeneratePass Developers
Verified AuthorSecurity researchers, cryptography engineers, and software developers dedicated to making browser-based cryptographic tools accessible and secure. We write guides with a focus on local execution, zero-trust patterns, and client-side data sovereignty.
Related Security Tools
Related Publications
Base64 Encoding Explained
A technical guide to Base64 encoding, explaining the mathematical bit-shifting process, padding logic, and modern use cases in web applications.
Base64 Myths Debunked: What Encoding Actually Does (and Doesn't Do)
Debunking the most common Base64 myths, explaining what Base64 encoding is, what it is not, and when you should—and shouldn't—use it.
JWT Security Guide: How JSON Web Tokens Work and How to Secure Them
A comprehensive guide to JWT security, covering token structure, signing algorithms, common vulnerabilities, and production best practices.