UUIDs Explained: The Math Behind 36-Character Identifiers
Developers use UUIDs such as 550e8400-e29b-41d4-a716-446655440000 as identifiers in databases, APIs, logs, and distributed systems. The useful question is concrete: how can a system generate unique identifiers without asking a central server for the next number?
1. What Is a UUID, Exactly?
A Universally Unique Identifier (UUID) is a 128-bit number, typically displayed as 32 hexadecimal digits separated by four hyphens: xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx.
The structure reveals version information:
- M (the 13th hex digit): Indicates the UUID version (1-8). For UUIDv4, M is always
4.
- N (the 17th hex digit): Indicates the variant. For standard UUIDs, N is
8, 9, a, or b.
With 128 bits, the total space is 2¹²⁸, or approximately 3.4 × 10³⁸ possible UUIDs. Generating 1 billion UUIDs per second for 100 years would produce about 3 × 10¹⁸ UUIDs, a tiny fraction of the available space.
2. The Seven Versions of UUID
Different UUID versions serve different needs:
UUIDv1: Time + MAC address
Based on the current timestamp (in 100-nanosecond intervals since October 15, 1582) and the machine's MAC address. The advantage is creation-time sorting. The disadvantage is privacy: anyone with the UUID can derive when and on which machine it was created.
UUIDv2: DCE Security
A rarely-used variant of v1 that embeds POSIX UID/GID. Largely obsolete.
UUIDv3: MD5 hash of namespace + name
Deterministic: given the same namespace and name, you always get the same UUID. Useful for generating IDs from existing unique values such as URLs or email addresses. Uses MD5, which is cryptographically broken, but UUIDv3 is not used for security purposes.
UUIDv4: Random
The most common version. 122 of the 128 bits are random. The primary risk is collision rather than cryptographic compromise, though 122 random bits make accidental collision negligible for ordinary systems.
UUIDv5: SHA-1 hash of namespace + name
Same deterministic concept as v3, but using SHA-1 instead of MD5. Prefer v5 over v3 in new systems.
UUIDv6: Time-ordered and field-compatible with v1
A reordering of v1 fields to make UUIDs sortable by creation time in a database-index-friendly way. v1 timestamps are stored in a way that breaks chronological sorting; v6 fixes this.
UUIDv7: Unix timestamp + random
The newest practical standard. The first 48 bits encode a Unix timestamp in milliseconds; the remaining bits are random. This makes UUIDv7 sortable by creation time, which helps database index performance compared with random UUIDv4 values. UUIDv7 is the recommended choice for most new applications.
UUIDv8: Vendor-defined
A catch-all for experimental or proprietary UUID formats.
3. "But What About Collisions?"
This is the question everyone asks about UUIDv4. The answer is math:
With 122 random bits, the number of UUIDs you'd need to generate to have a 50% probability of at least one collision follows the birthday problem formula:
n ≈ √(2 × 2¹²² × ln(1/(1-0.5))) ≈ 2.7 × 10¹⁸
That is 2.7 quintillion UUIDs. Generating 1 billion per second, you would need 85 years to reach a 50% collision probability. For practical application workloads, UUIDv4 collisions are not a realistic planning concern.
UUIDv5 and v3 have a different collision model: hash collisions. With SHA-1 (v5), the collision resistance is 80 bits. That is weaker than UUIDv4 randomness but still enough for ordinary deterministic identifier use.
4. UUIDs vs. Auto-Increment IDs
Many developers default to database auto-increment integers for primary keys. UUIDs offer important trade-offs:
| Property | Auto-Increment | UUID |
|---|
| Uniqueness scope | Single database | Universal |
| Sortable by time | Yes | Only v6/v7 |
| Guessable | Yes (sequential) | v4: No. v7: timestamp part yes |
| Index performance | Excellent | v4: Poor (random I/O). v7: Good |
| Offline generation | No (requires DB) | Yes |
| Storage size | 4-8 bytes | 16 bytes |
Use auto-increment IDs when the data never leaves a single database. Use UUIDs when records may be merged, synced, federated, or generated offline.
5. When to Use Each Version
A practical decision guide:
- Web app primary keys: UUIDv7. Sortable timestamps help B-tree indexes.
- Distributed systems / offline-first: UUIDv4. No coordination or timestamp dependency.
- Content-addressable IDs (from URLs, names, etc.): UUIDv5. Deterministic, reproducible, and derivable without a database lookup.
- Legacy systems that need sortable UUIDs without migration: UUIDv6. Wire-compatible with v1 but index-friendly.
Conclusion
UUIDs solve a practical distributed-systems problem: generate identifiers without central coordination. Choose v7 for most new database-backed applications, v4 for coordination-free random IDs, and v5 when the same input should produce the same identifier every time.