A UUID is a 128-bit identifier, usually written as 36 characters like 550e8400-e29b-41d4-a716-446655440000. The point of it is simple: any machine can generate one at any time, without checking with anyone else, and it will still be unique.
Why collisions effectively never happen
Version 4 UUIDs — the kind you'll use almost always — are made from 122 bits of random data. The number of possible values is around 5.3 × 10³⁶. To have a meaningful chance of generating the same one twice, you'd need to produce billions of them per second for decades.
This only holds if the randomness is genuinely unpredictable. A UUID built on JavaScript's Math.random() is neither cryptographically secure nor collision-safe in the way the specification intends. Proper generators use the platform's secure random source — in browsers, that's the Web Crypto API.
What the version number means
You'll see a 4 as the first character of the third group in a v4 UUID — that's the version marker. Version 1 UUIDs are built differently, embedding a timestamp and the generating machine's MAC address. That makes them sortable but leaks information about when and where they were created, which is why v4 is the common default.
When UUIDs are the right choice
- Distributed systems — multiple servers or services creating records simultaneously, with no shared counter to coordinate.
- Offline-first apps — a mobile client can create records offline and sync later without ID conflicts.
- Public-facing identifiers — sequential IDs in a URL reveal how many records you have and let people guess neighbouring ones. UUIDs don't.
- File and upload names — prefixing with a UUID means two users uploading "photo.jpg" never overwrite each other.
- Idempotency keys — sending a unique ID with a payment request lets the server safely ignore accidental duplicate submissions.
When a plain integer is better
UUIDs are not free. They're 16 bytes versus 4 or 8 for an integer, they don't sort meaningfully, and as a primary key they can fragment database indexes and hurt insert performance at scale. For a single application with one database, an auto-incrementing integer is smaller, faster, and easier to read in logs.
A common middle ground: use an integer primary key internally, and a separate UUID column as the public-facing identifier you expose in URLs and APIs.
Formatting details
RFC 4122 specifies lowercase as canonical, but UUIDs are defined to compare case-insensitively. Pick one and be consistent — and if you're merging data from sources that disagree, normalise the case before comparing.