14 categories See all →
home / blog / Developer

UUID Explained: What It Is and When to Use One

What a UUID actually is, the difference between v1, v4, and v5, the 8-4-4-4-12 format, and when a UUID beats an auto-increment integer ID.

Every backend developer eventually hits the "should this be an integer ID or a UUID" decision, usually when designing a new table. It's worth understanding what a UUID actually guarantees — and doesn't — before defaulting to one out of habit.

What a UUID is

A UUID (Universally Unique Identifier) is a 128-bit value, almost always written as 32 hexadecimal digits grouped into five sections separated by hyphens: 8-4-4-4-12, for example f47ac10b-58cc-4372-a567-0e02b2c3d479. That format isn't arbitrary — a few of those bits are reserved to encode the UUID's version and variant, which is how software can tell, just by looking at a UUID, which algorithm generated it.

"Universally unique" is a slight overstatement — it's more accurate to say "unique enough that collisions are not a practical concern." With 128 bits of entropy (for randomly generated versions), the number of possible UUIDs is roughly 3.4 × 10^38. Even generating billions of UUIDs per second, the probability of ever generating a duplicate by chance is astronomically small — small enough that essentially every production system treats UUIDs as unique without any coordination between the machines generating them.

The versions that actually matter

v1 — time-based. Built from the current timestamp plus the generating machine's MAC address. Guarantees uniqueness in a specific way (time + hardware identity), but it leaks information — you can extract the generation timestamp and the network card identifier from a v1 UUID, which is a privacy and security concern. You'll still encounter v1 in some legacy or specialized systems, but it's rarely the default choice today.

v4 — random. This is the one you'll see used by default almost everywhere today. It's generated from (ideally cryptographically secure) random bits, with a few fixed bits marking it as version 4. No timestamp, no machine identity, no coordination needed between generators — just randomness large enough that collisions aren't a realistic concern. If someone says "UUID" without specifying a version, they almost certainly mean v4.

v5 — name-based (deterministic). Generated by hashing a namespace identifier plus a name (using SHA-1). The key property: the same namespace + name combination always produces the exact same UUID, every time, on any machine. This is useful when you want a reproducible, stable ID derived from existing data — for example, generating a consistent UUID for a URL or email address without needing a lookup table, so the same input always maps to the same ID.

When a UUID beats an auto-increment integer

Distributed systems and offline-first generation. An auto-increment integer ID requires a single authority (the database) to hand out the next number — two separate services, or a client working offline, can't both safely generate ID #4,502 without coordinating. A v4 UUID can be generated anywhere, by anyone, with no coordination, no network round-trip, and no risk of collision. This matters a lot for mobile apps creating records offline, or microservices that each need to create IDs independently before a record ever touches a central database.

Merging databases without ID collisions. If you ever need to merge two databases — acquiring a company, combining regional shards, migrating between systems — auto-increment IDs from two separate systems will collide constantly (both have a row with id=1, id=2, etc.), forcing a painful remapping of every foreign key reference. UUIDs generated independently in each system essentially never collide, so a merge just works.

Not wanting to leak record counts. An auto-increment ID in a public URL (/invoices/1042) tells anyone looking that you've issued roughly 1,042 invoices, and lets them guess at other IDs by incrementing the number (a real enumeration/IDOR risk if authorization isn't airtight). A UUID in the same spot (/invoices/f47ac10b-58cc-4372-a567-0e02b2c3d479) reveals nothing about volume and isn't practically guessable.

When an integer ID is still the better choice

UUIDs aren't free. They're 128 bits versus 32 or 64 bits for a typical integer — roughly 4x the storage per ID, which adds up across every row and every index that references it. They're also not sequential (v4, specifically), which matters more than people expect: many databases (including common configurations of MySQL/InnoDB) perform significantly better with sequential primary keys, because random insertion order causes more index fragmentation and page splits than appending in order. For a single-database application with no merging or offline-generation needs, a plain auto-increment integer is simpler, smaller, faster to index, and entirely sufficient — reaching for UUIDs by default "because they're more scalable" without that actual requirement is adding real cost for a benefit you're not using.

Generate some

Our UUID Generator generates v4 UUIDs using the browser's built-in crypto.randomUUID() — meaning they're drawn from a cryptographically secure random source and follow the standard RFC format, not a simplified lookalike. It supports generating in bulk, with options for uppercase and braces formatting, useful when you need a batch of test IDs or are seeding a database.