If you have ever worked with a database, built an API, or traced a distributed system, you have almost certainly encountered UUIDs. They appear as primary keys, session tokens, file identifiers, and correlation IDs. They are everywhere in modern software -yet many developers use them without fully understanding the different versions, their tradeoffs, or the cases where a UUID might not be the best choice. This guide covers everything you need to know.
What is a UUID?
A UUID (Universally Unique Identifier) is a 128-bit number standardized in RFC 4122. It is typically represented as 32 hexadecimal digits separated by hyphens in the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -for example 550e8400-e29b-41d4-a716-446655440000. The design goal is that any system, anywhere in the world, can generate a UUID independently and be practically guaranteed that no other system will ever generate the same one. No central authority is needed. No coordination is required. The uniqueness guarantee comes from the combination of randomness, time, and address space.
UUID v4 -Random (Most Common)
UUID v4 is the most widely used UUID version. It is generated entirely from cryptographically secure random numbers -122 bits of randomness with the remaining 6 bits reserved for version and variant encoding. The probability of generating two identical v4 UUIDs is approximately 1 in 5.3 undecillion. In all practical scenarios UUID v4 is unique. Use v4 when you need a random, opaque identifier and do not need any embedded metadata. It is the right choice for most application development purposes.
UUID v1 -Time-Based
UUID v1 incorporates the current timestamp (in 100-nanosecond intervals since October 15, 1582) and a node identifier (typically a MAC address or random value) into the UUID. This means v1 UUIDs are roughly sortable by creation time and you can extract the creation timestamp from a v1 UUID. The tradeoff is that v1 UUIDs can reveal when and potentially where (MAC address) they were created, which can be a privacy or security concern. They are also not truly random so they should not be used where unpredictability is required.
UUID v5 -Deterministic (Name-Based)
UUID v5 is a name-based UUID generated by hashing a namespace UUID and a name string using SHA-1. The critical property of v5 is that it is deterministic -the same namespace and name will always produce the same UUID, on any machine, at any time. This is useful when you need a stable unique identifier for a known resource. For example you might generate a consistent UUID for a given URL, domain name, or product code without storing the UUID in a database. UUID v3 is the same concept but uses MD5 instead of SHA-1 -v5 is preferred because SHA-1 is stronger.
ULID -The Database-Friendly Alternative
ULID (Universally Unique Lexicographically Sortable Identifier) is a modern alternative to UUIDs designed to address a key weakness of UUID v4 in databases. A ULID encodes a 48-bit millisecond timestamp in its first 10 characters followed by 80 bits of randomness in the remaining 16 characters, encoded in Crockford's Base32 (URL-safe, no ambiguous characters). Because the timestamp comes first, ULIDs sort chronologically. This makes them excellent for database primary keys because new records are always inserted at the end of the index, avoiding the index fragmentation that random UUID v4 keys cause in B-tree indexes.
For database primary keys, prefer ULID or UUID v7 (time-ordered) over UUID v4. Random UUIDs cause B-tree index fragmentation which degrades write performance at scale.
UUID as Database Primary Keys -Pros and Cons
- ✅ Globally unique -safe to generate in distributed systems without coordination
- ✅ Can be generated client-side -no round-trip to the database needed
- ✅ Opaque -does not reveal record count or creation order (unlike auto-increment integers)
- ✅ Safe to expose in URLs -increment IDs allow enumeration attacks
- ❌ UUID v4 is random -causes B-tree index fragmentation degrading write performance
- ❌ Larger than integers -128 bits vs 32 or 64 bits, increases storage and index size
- ❌ Not human-friendly -harder to read, remember, or type than auto-increment IDs
- ❌ No built-in ordering -you cannot tell which record was created first from UUID v4
If you are using UUIDs as primary keys in PostgreSQL, MySQL, or another relational database at scale, benchmark UUID v4 vs ULID carefully. Random UUIDs can cause significant write performance degradation due to index fragmentation.