UUID v4 vs v7: Which Should You Use?
Compare random UUID v4 with time-ordered UUID v7 using RFC 9562, including database behaviour, privacy trade-offs and generation limits.
Use UUID v4 when a well-supported random identifier is enough. Consider UUID v7 when new records benefit from time-ordered values, especially in write-heavy databases. Neither version is a permission system, a secret token or a substitute for a database uniqueness constraint.
What a UUID guarantees—and what it does not
A UUID is a 128-bit identifier represented in a familiar hexadecimal and hyphenated form. RFC 9562 standardises the current layouts and replaced the older RFC 4122. UUIDs avoid a central issuing service for many workflows, but “universally unique” is an engineering objective rather than a registry checking every generated value.
Applications should still enforce uniqueness where duplicates would cause harm. A primary-key or unique constraint catches a collision or implementation fault that probability alone cannot.
UUID v4: random by design
Version 4 fills the identifier's random fields with random or pseudorandom bits while reserving the required version and variant bits. It does not intentionally reveal a creation timestamp and is supported across a wide range of languages, browsers and databases.
Its main operational drawback is ordering. Random values arrive across the index rather than near the newest values. At large scale, that can reduce locality and increase index maintenance compared with identifiers whose leading bytes rise over time. The real effect depends on the database, index and workload, so measure before redesigning a working system.
UUID v7: time first, randomness after
Version 7 places a Unix-epoch timestamp in milliseconds in the most significant 48 bits, followed by the version, variant and random or monotonic fields. Newer values therefore tend to sort by creation time when represented consistently.
This can improve index locality and make roughly chronological records easier to inspect. It also exposes approximate creation time to anyone who can read the identifier. A basic UUID v7 implementation that combines the current millisecond with random bits is time-ordered across different milliseconds, but it does not necessarily guarantee strict ordering for multiple values created inside the same millisecond.
Decision table
| Question | UUID v4 | UUID v7 |
|---|---|---|
| Primary characteristic | Random | Time-ordered with random fields |
| Approximate creation time visible | No timestamp by design | Yes |
| Natural insertion locality | Usually scattered | Usually increasing over time |
| Ecosystem maturity | Very broad | Growing after RFC 9562 |
| Strict order within one millisecond | Not applicable | Only with an appropriate monotonic method |
| Good default when unsure | Yes, if random IDs meet the system's needs | Use when ordering/locality is a deliberate requirement |
UUIDs are identifiers, not access controls
Do not assume that an unguessable-looking identifier authorises access. Every request still needs permission checks. UUID v4 can make casual enumeration harder than sequential integers, but leaked values remain usable if the application treats possession as permission.
UUID v7's embedded time can reveal when an account, order or event was created. That may be harmless internal metadata or an unwanted information leak in a public URL. Review that trade-off before exposing values.
Generation checklist
- Choose the version from application requirements, not trend alone.
- Use the operating system or runtime's cryptographic random source.
- Keep the standard variant and version bits intact.
- Store UUIDs consistently as a native type or 16 bytes where supported.
- Add a unique constraint when duplication would be damaging.
- Do not use a UUID as proof of authentication or authorisation.
- Test sort order and index behaviour with the actual database and workload.