UUIDv4 identifiers: randomness, collisions and validation

Read the version and variant bits, estimate collision risk responsibly and keep identifiers separate from access control.

A UUIDv4 is a randomly generated identifier with a standard 128-bit layout. Six bits identify the version and variant, leaving 122 random bits in the usual UUIDv4 form. That provides a very large identifier space, but the identifier is not a permission check or proof of ownership.

Use UUIDs to label records when decentralised generation or opaque identifiers fit the system. Keep database uniqueness constraints and access control in place. Randomness makes accidental collisions unlikely; it does not make every implementation correct or every record safe to expose.

Read the standard text layout

The UUID generator creates version 4 identifiers using the browser's cryptographic random facilities. The familiar text form contains hexadecimal groups separated by hyphens in an 8-4-4-4-12 pattern.

xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx

The version digit is 4.
The variant digit y is 8, 9, a or b.
The remaining positions carry random bits.

The hyphens are formatting, not additional randomness. Uppercase and lowercase hexadecimal can represent the same UUID value, though a system should choose a consistent canonical display. Store and compare identifiers according to a defined representation rather than mixing arbitrary text forms.

A string with the right shape is not necessarily a valid UUIDv4. Check the version and variant bits as well as the hexadecimal groups. Conversely, a valid UUID of another version should not be called version 4 merely because it uses the same hyphen pattern.

Use a cryptographic source

UUIDv4 generation requires suitable random bits. Browser crypto.randomUUID or an appropriate construction using cryptographic random bytes can provide them in supported environments. Math.random is not the right source for security-sensitive random identifiers.

A broken generator can repeat values despite the enormous theoretical space. Cloned process state, a poor random source or application caching can create collisions that probability calculations for ideal independent randomness do not predict. Use standard platform primitives and test the application's integration.

Do not generate one UUID at module load and reuse it for every new record by mistake. The call must occur at the intended creation boundary. A large namespace cannot protect code that repeatedly stores the same already-generated value.

UUID decisions in an application
DecisionUseful ruleReason
GenerationUse a standard cryptographic implementationProbability assumptions require suitable randomness
ValidationCheck the intended version and variantText shape alone is incomplete
StorageUse a consistent representation and unique constraintCatch errors and rare duplicates
AuthorisationCheck the caller's access to the recordAn opaque ID is not permission
OrderingChoose a design suited to the databaseRandom values do not encode creation order

Estimate collision risk with the birthday model

For n independently generated values in a space of size N, a useful small-probability approximation is n(n-1)/(2N). For UUIDv4, N is 2 to the power of 122 when the random bits are generated correctly. The number of pairs grows roughly with the square of the number generated.

At one billion UUIDv4 values, the approximation is about 9.4 times 10 to the power of minus 20. At one trillion values, it is about 9.4 times 10 to the power of minus 14. These are mathematical estimates under the independence and uniformity assumptions, not measurements of your generator.

Keep the distinction between accidental collision and adversarial guessing. Collision analysis asks whether any pair in a generated population matches. Guessing an existing secret token involves a different question and depends on request limits, exposure and the number of valid targets.

Retain a database uniqueness constraint

A unique constraint protects against rare collisions and ordinary programming errors. If an insert fails because the identifier already exists, handle it according to the application's creation semantics. For an internally generated new record, generating a fresh value and retrying may be appropriate.

Do not automatically retry an externally supplied identifier without considering idempotency. A repeated request with the same ID may intentionally refer to the same operation. Decide whether the identifier is a record key, an idempotency key or a user-provided reference; those roles need different handling.

Review index behaviour for the chosen database. Random keys can have different locality characteristics from ordered identifiers. That is a performance and storage design issue, not evidence that UUIDv4 is cryptographically weak. Measure the actual workload before changing identifier schemes.

Create records safely from two clients

Suppose two offline clients create notes and later sync them. Each can generate a UUIDv4 locally for a new note, avoiding the need to reserve a sequential ID from the server first. The server still validates the identifier, checks ownership and applies a unique constraint during sync.

If both clients submit the same identifier because a note was copied or a request retried, the server must decide whether it is the same logical note or a conflict. Random generation does not resolve business semantics. Include a version or sync protocol suited to the application.

Test duplicate submissions deliberately. Confirm that a retry does not create two notes and that one user's supplied ID cannot overwrite another user's record. These are realistic failure modes that a collision-probability calculation will not catch.

Keep creation time in a separate field if using UUIDv4. The identifier does not encode a timestamp, and sorting its text does not recover chronological order. Use explicit timestamps and stable tie-breaking where the interface requires ordering.

Keep identifiers separate from secrets

An unguessable-looking record URL still needs authorisation. A user who obtains another record's UUID through a shared link, log or response should not automatically gain access unless the product intentionally uses a capability-link design.

If the design intentionally grants access through possession of a token, use a token format, entropy budget, expiry and revocation model chosen for that purpose. A UUID's standard layout may be acceptable for some identifier tasks, but choosing it should not bypass the security design.

Do not infer identity from the ID's version. UUIDv4 does not contain a MAC address or timestamp in its random layout. Other UUID versions have different constructions, so privacy claims must refer to the version actually used.

Validate without changing the intended value

Reject malformed groups, non-hexadecimal characters and unexpected versions where the API contract requires UUIDv4. Decide whether canonical case and hyphen formatting are required or normalised. Apply the same rules at client and server boundaries.

A validator should not silently strip arbitrary punctuation until an input resembles an identifier. That can hide data errors and make logs disagree with stored values. Return a clear validation error and preserve the original input in a safe diagnostic context.

Be careful with nil and maximum UUID values if the application accepts general UUIDs. They have special roles in the standard and should not accidentally become ordinary randomly generated records. A version-specific creation path avoids some of that ambiguity.

Test the boundary, not a claim of perfect randomness

A small test batch can confirm format, version bits and that the generator is called for each item. It cannot prove the random source's statistical quality or guarantee no future collision. Rely on the platform's cryptographic primitive and test your use of it.

For exports, decide whether identifiers themselves are sensitive in context. A UUID can link records even though it contains no obvious personal information. Avoid assuming that an opaque string is anonymous merely because it is hard to read.

Document the chosen UUID version with the API. If a future migration introduces an ordered version, consumers should not assume the new layout has the same privacy or sorting properties as UUIDv4.

Frequently asked questions

Can UUIDv4 ever collide?

The probability is nonzero, though very small with correct independent randomness. Programming errors can dominate that theoretical risk. Keep unique constraints and sensible retry or conflict handling instead of treating mathematical rarity as permission to omit validation.

Does UUIDv4 contain my MAC address?

The version 4 construction uses random bits plus version and variant fields. It does not encode a MAC address or creation timestamp. Other UUID versions differ, so inspect the version before making a claim about what an identifier contains.

Can I use a UUID as an access-control check?

No. The server must verify that the caller is authorised for the referenced record. An ID can leak through normal application paths. If possession intentionally grants access, design it as a capability token with appropriate lifecycle controls.

Why do all generated values have a 4 in the same place?

That digit encodes the version. The variant also constrains another position. Those fixed bits are why UUIDv4 has 122 random bits rather than 128. The remaining random space is still extremely large.

Should I sort UUIDv4 values by creation time?

They do not encode creation time. Store an explicit timestamp and use an appropriate ordering rule. If database locality motivates another identifier version, evaluate that design separately and document its different properties.

Can a regular expression prove the generator is secure?

No. It can check text structure and some fixed bits. It cannot establish the source or independence of random values. Use a trusted implementation and test the application's creation boundary and duplicate handling.

What should an API document about UUIDs?

Specify the version, accepted text form, normalisation rules, uniqueness scope and whether clients may supply identifiers. Explain retry and conflict semantics. These details matter more to interoperability than merely stating that a field is a UUID.

Sources and further reading

50 useful tools · ↑ ↓ to navigate · Enter to open · Esc to close