The problem UUIDs solve
Imagine two servers on opposite sides of the world, both creating new user records at the same moment, with no way to talk to each other in that instant. Each needs to assign the new record an identifier. If they both use simple counting — user 1, user 2, user 3 — they will inevitably assign the same number to different users, and when the data is later combined, those records will collide. You need a way for each server to generate an identifier on its own that will never clash with one generated anywhere else.
That is exactly what a UUID does. A UUID — Universally Unique Identifier — is a 128-bit value, usually written as 32 hexadecimal characters in five groups separated by hyphens. The whole point is that any system can generate one independently, with effectively no chance of ever producing the same value as another system.
How UUID version 4 works
There are several versions of UUID, but by far the most common today is version 4, which is based on random numbers. A UUID v4 is generated by taking 128 random bits and then fixing a few of them to mark it as version 4. That leaves 122 bits of pure randomness.
One hundred and twenty-two bits of randomness is an almost incomprehensibly large space — roughly 5.3 undecillion possible values, a number with 36 digits. The practical consequence is that if you generated a billion UUIDs per second for a hundred years, the probability of a single collision would still be vanishingly small. This is why developers treat UUID v4 as unique in practice, even though it is technically 'only' extremely improbable to repeat.
Where UUIDs are the right choice
UUIDs shine wherever you need to create identifiers without coordinating through a single central counter:
- Primary keys in distributed databases, where multiple nodes insert records independently.
- Client-generated IDs, where an app creates a record offline and syncs it later.
- Correlation IDs for tracing a single request as it moves through many services.
- Idempotency keys, so retrying a request does not create duplicate actions.
- Test fixtures and mock data, where you just need realistic unique values quickly.
Where UUIDs are the wrong choice
UUIDs are not a universal answer, and using them incorrectly causes real problems. First, a UUID is not a secret. Because v4 is random it is hard to guess, but it is still exposed in URLs, logs, and responses. Never use a UUID as a security token, a password reset key, or anything that grants access. Use a purpose-built cryptographic token for those.
Second, a UUID does not prove anything about identity or authorisation. Knowing a record's UUID does not mean a user is allowed to see it. You still need proper access checks. Treating 'they have the ID, so they must be allowed' as a rule is a classic security mistake.
Third, UUIDs have a performance cost as database keys. They are larger than integers and, being random, they do not cluster nicely in an index, which can slow down inserts and increase index size in very large tables. For a small application this never matters; for a table with billions of rows it can, and there are ordered UUID variants designed to address it.
Generating them safely
The single most important rule when generating UUID v4 values is to use a cryptographically strong random source. Modern browsers expose exactly this through the built-in crypto API, and JavaScript's crypto.randomUUID() uses it directly. Weak random generators can produce predictable or repeating values, which undermines the entire guarantee. A browser-based UUID generator that uses the platform crypto API gives you correct, standards-compliant values instantly, without sending anything to a server.
Key takeaways
- A UUID is a 128-bit identifier designed to be unique without central coordination.
- Version 4 relies on 122 bits of randomness, making collisions effectively impossible.
- Use them for distributed keys, correlation, and mock data — not as secrets or access tokens.
- Always generate them from a cryptographically strong random source.