How a version 4 UUID is built
A v4 UUID is almost entirely random. Of its 128 bits, 6 are fixed: four mark the version (always 4) and two mark the variant (always 10 in binary). The other 122 bits are random. That is why the third group always starts with 4 and the fourth group always starts with 8, 9, a or b:
xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
^ ^
| +-- y is one of 8, 9, a, b
+------- 4 = version 4
| Part | Bits | Value |
|---|---|---|
| Random | 48 | random |
| Version | 4 | 0100 |
| Random | 12 | random |
| Variant | 2 | 10 |
| Random | 62 | random |
How likely is a collision?
With 122 random bits there are about 5.3 × 1036 possible v4 UUIDs. By the birthday rule, you need to create about 2.7 × 1018 of them to reach a 50% chance that two are equal. Making one billion UUIDs every second would take about 85 years to get there. In real systems, a collision comes from a broken random source, copied state (for example a virtual machine snapshot restored twice), or a bug, almost never from chance.
What makes the randomness good
This page uses crypto.getRandomValues(), the cryptographically secure generator of the browser, and sets the version and variant bits as defined in RFC 9562. Avoid generators built on Math.random(): its output can be predicted and it is not designed to avoid repeats. When you use a library, check that it uses the operating system's secure source.
Formats you can copy
- Standard:
f47ac10b-58cc-4372-a567-0e02b2c3d479 - No hyphens:
f47ac10b58cc4372a5670e02b2c3d479(32 characters) - Braces:
{f47ac10b-58cc-4372-a567-0e02b2c3d479} - URN:
urn:uuid:f47ac10b-58cc-4372-a567-0e02b2c3d479 - Base64URL: 22 characters, shorter for URLs and file names. The Base64URL encoder explains the alphabet.
Validate a v4 UUID
^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
Use the case-insensitive flag. This regular expression accepts only version 4. To accept all versions, or to see why a value is rejected, use the UUID validator.
Generate a v4 UUID in code
// JavaScript crypto.randomUUID(); // "36b8f84d-df4e-4d49-b662-bcde71a8764f" # Python import uuid uuid.uuid4() // Java UUID.randomUUID(); // C# Guid.NewGuid(); // Go id := uuid.New() // github.com/google/uuid // Rust (uuid crate with the v4 feature) Uuid::new_v4() -- PostgreSQL 13 and later SELECT gen_random_uuid(); # Linux shell cat /proc/sys/kernel/random/uuid
Storing v4 UUIDs
- Use the native type where there is one:
uuidin PostgreSQL,uniqueidentifierin SQL Server. In MySQL and MariaDB,BINARY(16)uses 16 bytes against 36 forCHAR(36). - Random keys land in random places in a B-tree index, which causes page splits and a larger, slower index when a table is big. If that matters, a time-ordered UUID v7 is the better key.
- A UUID is not a secret. It is fine as an id and not good enough as the only guard on private data.
Need many at once? Use the bulk UUID generator. All versions and options are on the main UUID generator, and the guide What is a UUID? covers the rest.