Why UUIDs exist
The problem they solve is coordination. Sequential database identifiers require something central to hand them out, which becomes awkward the moment you have several databases, offline clients that need to create records before syncing, or a system where the identifier must be known before the write happens.
A UUID is large enough and random enough that any number of independent systems can generate them without ever consulting each other, and rely on never colliding. That property is worth a great deal in distributed systems, and it is the reason UUIDs appear everywhere from database keys to file names to correlation identifiers in logs.
The cost is size and readability. A UUID is 36 characters against a handful for an integer, it is impossible to read aloud reliably, and it gives you no sense of ordering or scale.
How unlikely a collision really is
There are roughly 5.3 undecillion possible version 4 UUIDs — a number with 36 digits. To reach a 50% chance of any collision you would need to generate about 2.7 quintillion of them.
Put concretely: generating a billion UUIDs every second, it would take around 85 years to reach a one-in-a-billion chance of a single duplicate. This is not a risk to design around, and effort spent guarding against it is better spent elsewhere.
The genuine risk is not randomness but implementation. UUIDs generated from a weak source — Math.random, a poorly seeded generator, or a library that silently fell back to one — can be predictable, and predictable identifiers used for anything resembling a session or a private link are a security hole. This page uses the browser's cryptographic generator.
Versions, and when v4 is not what you want
Version 4 is random and is the right choice for most purposes. Version 1 encodes a timestamp and the generating machine's network address, which makes it sortable and also means it leaks information about where and when it was created. Version 7, more recent, encodes a timestamp without the hardware identifier.
That ordering property matters more than it sounds for databases. Random UUIDs scatter inserts across an index rather than appending to the end, which fragments pages and hurts write performance on large tables — noticeably so in engines that cluster on the primary key.
So the honest guidance is: version 4 for identifiers that must not reveal anything, version 7 when you want uniqueness and insert performance together and your database supports it.
Practical formatting
The canonical form is 36 characters: 32 hexadecimal digits in five hyphen-separated groups, lower case. Most systems expect exactly this, and it is the safe default.
Some do not. Microsoft's ecosystem traditionally wraps them in braces and frequently uses upper case. Compact 32-character forms without hyphens appear where storage or URL length matters. None of these change the underlying value, only its representation, so converting between them is always safe.
One caution: if you store UUIDs as text, pick one representation and enforce it. A table containing the same identifier in three different casings with and without hyphens will not join to itself, and that bug is much harder to find than it should be.