UUID v4 vs v7: Which Should You Use?
Both v4 and v7 are 128-bit identifiers you can generate anywhere without coordinating with a central server, and both are effectively guaranteed never to collide. The difference is what's encoded in those bits โ and it changes which one you actually want for a given job.
UUID v4: pure randomness
Version 4 is 122 random bits (the remaining 6 are fixed to mark the version and variant), typically drawn from a cryptographically secure random source. Nothing about a v4 value tells you anything about when or where it was generated โ it's just noise, by design. That makes it the safe, general-purpose default: API keys' companions, idempotency keys, correlation IDs, test fixtures, and any identifier you're comfortable exposing publicly without worrying about what it might reveal.
UUID v7: time first, randomness after
Version 7 restructures those same 128 bits: the first 48 bits hold a millisecond-precision Unix timestamp, and the rest is filled with randomness. Because that timestamp is stored most-significant-byte-first and comes at the start of the value, v7 UUIDs sort into chronological order as plain strings โ generate a batch of them over time and sorting alphabetically gives you the same order as sorting by creation time, with no extra logic required.
Why v7 helps database performance specifically
This sorting property is the whole reason v7 exists. A table keyed on random v4 values inserts new rows at random points throughout its index, which is expensive for a B-tree structure to maintain and makes "give me everything created in the last hour" a much harder query to answer efficiently. A table keyed on v7 values instead appends new rows near the end of the index โ the same pattern as a classic auto-incrementing integer key โ while still keeping every benefit of a UUID: no central counter, no coordination needed between multiple servers generating IDs concurrently, and no risk of collision.
The trade-off: v7 reveals timing
The cost of that ordering is that a v7 value tells anyone who looks at it roughly when it was created, down to the millisecond. For an internal database key that's almost always a complete non-issue. It matters more for an identifier that gets exposed publicly โ in a URL, say โ where you might specifically not want to reveal exactly when a record, order, or account was created. That's the one scenario where reaching for v4 instead is the more deliberate choice, not just the default.
Choosing between them
- Pick v7 for database primary keys and anything else where insert performance and range-by-time queries matter, and where creation timing being visible is a non-issue.
- Pick v4 for anything exposed publicly where you don't want timing information leaking, or whenever you just want the simplest, most timing-agnostic identifier and don't have a specific reason to choose otherwise.
Frequently asked questions
Is v7 a replacement for v4?
Not entirely โ they solve different problems. v7 is generally the better database primary key; v4 is still the right choice whenever you specifically don't want the identifier to reveal when it was created.
Does using v7 leak sensitive information?
It reveals roughly when the ID was created, down to the millisecond. That's usually harmless, but avoid it for identifiers where hiding creation timing specifically matters.
Can v4 and v7 collide with each other?
No. The version digit is part of the value (4 or 7), so a v4 UUID and a v7 UUID can never be equal.
Why do v7 UUIDs help database performance specifically?
Because they sort chronologically as plain strings, new rows insert near the end of an index instead of scattering randomly through it, which keeps B-tree inserts cheap and allows efficient range scans by creation time.