9 min read

UUID v4 vs UUID v7: Which Should You Use?

Compare UUID v4 and UUID v7, understand B-tree database index fragmentation, evaluate timestamp privacy, and choose the right identifier for your architecture.

Choosing a primary-key strategy affects storage, indexing, replication, and how IDs are generated across services. UUID v4 supports decentralized generation and makes simple sequential guessing impractical, but its random insertion pattern can reduce B-tree locality compared with time-ordered keys.

RFC 9562 standardizes time-ordered UUID v7. As a rule of thumb, consider v7 for database keys and event records that benefit from time locality; use v4 when you need a random identifier without an embedded creation time. Neither version should serve as an authentication secret or bearer token: generate security tokens with a dedicated cryptographic token API.

You can generate both versions using ToolPorta's UUID Generator. This guide explains their layouts, database-locality trade-offs, timestamp exposure, clock behavior, and the requirements that should drive the decision.

The technical anatomy of UUID v4 vs UUID v7#

A Universally Unique Identifier (UUID) is a 128-bit label formatted as a sequence of 32 hexadecimal digits separated by hyphens in an 8-4-4-4-12 grouping (36 characters total). Both UUID v4 and UUID v7 follow this canonical layout, but they populate the bits with entirely different data.

UUID v4: Pure pseudorandomness#

RFC 9562 defines UUID v4 as random or pseudorandom data with six structural bits. It recommends a cryptographically secure pseudorandom number generator when unguessability matters; the quality of a v4 UUID therefore depends on its generator.

  • Version bits (4 bits): Set to 4 (0100 binary) at the start of the third group.
  • Variant bits (2 bits): Set to 10 binary (represented by hexadecimal digits 8, 9, a, or b) at the start of the fourth group.
  • Random entropy (122 bits): The remaining 122 bits are random.

Example UUID v4:

TEXT
1f47ac10b---a567-2               ^    ^3         version   variant 

The 122 variable bits provide 2^122 possible v4 values. With a sound random generator, accidental collisions are extremely unlikely, but UUIDs are not a substitute for uniqueness constraints or authorization checks.

UUID v7: Time-ordered locality with entropy#

Standardized in 2024 under RFC 9562, UUID v7 addresses the fundamental flaw of UUID v4: the complete absence of sequential ordering. UUID v7 embeds a millisecond-precision Unix timestamp in the high-order bits, followed by randomness:

  • Unix timestamp (48 bits): An unsigned 48-bit integer representing the number of milliseconds since the Unix epoch (1970-01-01T00:00:00Z). This timestamp will not overflow until approximately the year 10889 AD.
  • Version bits (4 bits): Set to 7 (0111 binary) at the start of the third group.
  • rand_a region (12 bits): Random by default; an implementation may use some or all of it for extra timestamp precision or a counter.
  • Variant bits (2 bits): Set to 10 binary.
  • rand_b region (62 bits): Random data by default; some monotonic generation methods may use part of it as a counter.

Example UUID v7:

TEXT
1----2|--- -bit timestamp ---| ^    ^  |------ random/optional monotonic data ------|3                     version   variant

Because the most significant 48 bits represent an ascending millisecond timestamp, UUID v7 values sort chronologically when compared using standard lexicographical or byte-level string sorting.

Why UUID v4 hurts database performance (The B-tree problem)#

To understand why UUID v7 was created, you must look at how relational database storage engines (such as PostgreSQL, MySQL InnoDB, and SQLite) store primary keys.

Random I/O and page splits#

Relational databases index primary keys using B+ trees. A B+ tree keeps rows sorted on disk inside fixed-size storage pages (typically 8KB or 16KB).

When you insert records with auto-incrementing integers or time-ordered keys, each new record appends to the end of the highest storage page. Once a page fills up, the engine allocates a new page sequentially. This is known as sequential I/O.

With UUID v4, every generated key has a completely unpredictable value. When inserting 100,000 rows with UUID v4:

  1. The database must insert each key into a random leaf page in the B-tree.
  2. If the target page lacks space, the engine may split or reorganize the page and update index pointers.
  3. Repeated inserts across the keyspace can increase page churn, write amplification, and cache pressure. The effect depends on the database engine, fill factor, table size, storage, and workload.

Buffer pool cache thrashing#

As database tables grow beyond available RAM, the database engine can no longer keep the entire index in memory (the InnoDB buffer pool or PostgreSQL shared buffers).

With UUID v7, values from later milliseconds compare after earlier values, so recent inserts tend to target a narrower part of an index. UUID v4 distributes inserts across the keyspace. V7 often improves locality, but the throughput difference must be benchmarked with your database schema, hardware, concurrency, and query pattern.

Common pitfalls and edge cases#

Choosing between v4 and v7 involves several critical trade-offs regarding privacy, clock drift, and collisions.

1. Timestamp leakage and security risks#

The most significant disadvantage of UUID v7 is that it exposes the creation time of the resource.

The first 12 hexadecimal characters of a UUID v7 encode the exact millisecond the ID was minted. In many systems, leaking timestamps poses severe security and privacy issues:

  • User enumeration: If user IDs are UUID v7, an attacker can determine exactly when any user signed up.
  • Operational metadata: An observed v7 value reveals its millisecond timestamp and may expose when a resource was created. It does not, by itself, reveal total sales or record counts.
  • Secret tokens: Do not use either UUID version as a bearer credential. Timestamp leakage makes v7 less opaque, while RFC 9562 warns that UUIDs in general must not be assumed hard to guess.

Rule: Use v4 rather than v7 when an identifier must not reveal creation time. For password resets, sessions, API keys, and confirmation links, use a dedicated cryptographic token generator and enforce expiration, one-time use, and server-side validation.

2. Clock drift and NTP adjustments#

UUID v7 relies on system clocks. If a physical server's clock drifts backward due to an Network Time Protocol (NTP) step adjustment or virtual machine pause, newly generated IDs could theoretically have earlier timestamps than previously generated IDs.

RFC 9562 describes optional counters and monotonic-random techniques. Implementations that require strict ordering must explicitly handle clock rollback, counter rollover, and batches created within one millisecond. Random bits reduce collision probability across nodes, but they do not repair chronological ordering between unsynchronized clocks.

3. Collision probability within the same millisecond#

Developers sometimes worry that generating thousands of UUID v7 identifiers within the same millisecond on a single server will cause collisions.

In the basic layout, all 74 non-timestamp, non-structural bits may be random. Two independently generated values in the same millisecond match with probability 1 in 2^74, but collision risk across a batch follows the birthday bound and grows with the square of the batch size. Use a maintained implementation and retain a database uniqueness constraint.

UUID v4 vs UUID v7 comparison table#

FeatureUUID v4UUID v7Architectural Impact
Standard SpecificationRFC 4122 / RFC 9562RFC 9562 (May 2024)Both are official IETF standards
SortabilityNo creation-time orderOrdered by millisecond timestamp; same-millisecond order is implementation-dependentv7 supports time-oriented scans
Database IndexingInserts are spread across the keyspaceRecent values usually cluster in a narrower rangeBenchmark the actual workload
Random Bits122Up to 74; optional monotonic fields may use someGeneration strategy matters
Embedded TimeNoneExposes the millisecond timestampChoose v4 when time metadata must be hidden
Security TokensNot a bearer-token formatNot a bearer-token formatUse a dedicated token generator
Database SupportWidely accepted by UUID typesSame 128-bit storage; built-in generation variesPostgreSQL 18 includes uuidv7(); older versions can store v7 values

How to choose: Practical decision framework#

Use this simple 4-step decision tree to choose the right identifier for your project:

  1. Is the identifier used as a database primary key or clustered index?
    • Yes → Test UUID v7 against your workload; its time locality can reduce random index insertion.
    • No → Proceed to Step 2.
  2. Is the identifier a security credential, reset token, or session secret?
    • Yes → Use UUID v4 for the identifier, provided the generator is trustworthy.
    • No → Proceed to Step 3.
  3. Does the ID appear in public URLs where business volume must remain secret?
    • Yes → Use UUID v4 or a carefully sized compact identifier.
    • No → Proceed to Step 4.
  4. Do you need compatibility with legacy Microsoft Windows or COM systems?
    • Yes → Confirm the exact GUID byte and text conventions required by that integration.
    • No → Choose from the requirements above; v7 is a strong candidate for database-oriented IDs, not a universal default.

If you are writing backend services, inspect our JavaScript UUID guide or Python UUID guide for code snippets implementing RFC 9562 v7 generators.

Frequently asked questions#

Can I store UUID v7 in an existing PostgreSQL or MySQL UUID column?#

Yes. Both UUID v4 and UUID v7 conform to the identical 128-bit binary representation defined by RFC 9562. In PostgreSQL, UUID v7 stores seamlessly in the native uuid column type. In MySQL, it stores efficiently in BINARY(16) with full sorting support. You do not need to alter your database schema to start using UUID v7.

Does UUID v7 replace UUID v1?#

Yes. UUID v1 also included a timestamp, but its implementation had two major design flaws: it leaked the physical machine's MAC address (a severe security vulnerability), and its timestamp bit layout placed the lowest-order time bits first, preventing standard lexicographical sorting. RFC 9562 explicitly introduced UUID v7 to replace UUID v1.

Can I extract the creation timestamp from a UUID v7?#

Yes. You can extract the first 48 bits, convert the hexadecimal value to a decimal integer, and read it as a Unix timestamp in milliseconds. For example, in JavaScript:

JavaScript
1function getTimestampFromUuidV7(uuid) {2  const hex = uuid.replace(/-/g, "").slice(, );3  return new Date(parseInt(hex, ));4}

Is UUID v7 officially standardized?#

Yes. UUID v7 was standardized in May 2024 by RFC 9562, which obsoleted RFC 4122. Support is version-specific: for example, Python added uuid.uuid7() in 3.14, .NET added Guid.CreateVersion7() in .NET 9, and the maintained Node.js uuid package supports v7. Check the documentation for the exact runtime or library version you deploy.

Does UUID v7 eliminate the need for an auto-incrementing integer?#

No. Auto-incrementing integers remain compact, simple, and efficient when one database owns ID allocation. UUID v7 is useful when IDs must be generated before insertion or across independent nodes. The choice also affects foreign-key size, index size, replication, exposure of record counts, and operational tooling.

Selecting the right identifier format ensures your application scales smoothly without painful database migrations later. Explore ToolPorta's identifier toolset:

  • Use the UUID Generator to generate bulk batches of RFC 9562 UUID v7 and UUID v4 identifiers.
  • Use the GUID Generator when formatting identifiers for .NET, C#, and Microsoft Windows registries.
  • Use the NanoID Generator for URL-friendly, compact, collision-resistant string IDs.
  • Read our JavaScript UUID guide for implementation benchmarks.