DEV Community

Genory Team
Genory Team

Posted on

UUID v4 vs UUID v7: Which One Should Developers Use in 2026?

UUIDs are everywhere.

They identify users, orders, API resources, database rows, events, uploads and almost anything else that needs a unique ID without relying on a central counter.

For years, UUID v4 has been the obvious default.

Then UUID v7 arrived.

Both produce 128-bit identifiers. Both can work well in distributed systems. But they solve the problem differently — and that difference can matter once your application starts storing millions of records.

So when should you use UUID v4, and when does UUID v7 make more sense?

Let's compare them.

UUID v4 in one sentence

UUID v4 is essentially a randomly generated identifier.

A typical UUID v4 looks like this:

550e8400-e29b-41d4-a716-446655440000
Enter fullscreen mode Exit fullscreen mode

The important property is that independently generated UUIDs have an extremely low probability of colliding.

That makes v4 convenient for distributed systems because multiple services can generate IDs without coordinating with one another.

You don't need:

  • a central sequence
  • a database round trip
  • a shared counter
  • knowledge of previously generated IDs

Generate one and move on.

Why UUID v4 became so popular

UUID v4 has several attractive properties.

1. It is simple

Most languages and platforms already have mature support for UUID v4.

For example, modern JavaScript can generate one with:

const id = crypto.randomUUID();

console.log(id);
Enter fullscreen mode Exit fullscreen mode

There is very little to configure.

2. Generation is decentralized

Imagine several application servers creating new records at the same time.

With an auto-incrementing integer, the database usually becomes responsible for assigning the next value.

With UUIDs, each server can generate its own identifier before the record even reaches the database.

That is useful for:

  • distributed systems
  • offline workflows
  • event generation
  • message queues
  • client-side object creation
  • microservices

3. IDs do not reveal obvious sequence counts

Consider URLs such as:

/orders/18421
/orders/18422
/orders/18423
Enter fullscreen mode Exit fullscreen mode

Someone can immediately see that the values are sequential.

A UUID looks more like:

/orders/550e8400-e29b-41d4-a716-446655440000
Enter fullscreen mode Exit fullscreen mode

This makes the identifier less predictable.

But an important warning:

An unpredictable identifier is not an authorization mechanism.

Your application must still check whether the current user is allowed to access that resource.

UUIDs are identifiers, not passwords.

The downside of randomness

Randomness is also where UUID v4 can become less attractive for some databases.

Imagine a database index containing identifiers in sorted order.

Now insert these random values:

a82f...
14c9...
f931...
72ab...
09e1...
Enter fullscreen mode Exit fullscreen mode

New records may belong in completely different areas of the index.

Depending on your database, storage engine, index structure and workload, highly random inserts can create more scattered writes than mostly increasing values.

This does not mean:

UUID v4 is always slow.

That would be an oversimplification.

Database behavior depends on many factors:

  • database engine
  • UUID storage type
  • index implementation
  • page size
  • write volume
  • caching
  • hardware
  • query patterns

For many applications, UUID v4 performs perfectly well.

But the desire for UUID-style decentralized identifiers that also have useful time ordering is one reason UUID v7 is interesting.

What UUID v7 changes

UUID v7 still gives you a 128-bit UUID, but part of the value represents a Unix timestamp with millisecond precision.

The remaining portion provides randomness.

Conceptually, think of it like:

TIME + RANDOMNESS
Enter fullscreen mode Exit fullscreen mode

rather than:

RANDOMNESS
Enter fullscreen mode Exit fullscreen mode

This gives UUID v7 an important property:

UUIDs generated at different times naturally group by generation time.

A UUID v7 might look like:

0199a4c2-96f8-7b32-a847-84e7f61a66d9
Enter fullscreen mode Exit fullscreen mode

It still looks and behaves like a UUID.

But unlike v4, it contains temporal information.

Why time ordering can be useful

Suppose your application creates these records:

10:00 → record A
10:01 → record B
10:02 → record C
10:03 → record D
Enter fullscreen mode Exit fullscreen mode

UUID v4 values might sort like:

d82...
19a...
f71...
52c...
Enter fullscreen mode Exit fullscreen mode

There is no relationship between lexical order and creation time.

UUID v7 values generated across different milliseconds naturally group more like:

0199a...
0199b...
0199c...
0199d...
Enter fullscreen mode Exit fullscreen mode

This can be useful for systems that create large numbers of records.

Potential use cases include:

  • event tables
  • logs
  • transactions
  • orders
  • messages
  • activity feeds
  • distributed writes

Time-grouped identifiers can also behave more naturally in some indexed storage workloads.

Again, that does not guarantee that changing from v4 to v7 will magically make your database faster.

Benchmark your actual workload.

UUID v4 vs UUID v7

Here is the practical comparison.

Feature UUID v4 UUID v7
Main input Randomness Timestamp + randomness
Decentralized generation Yes Yes
Natural time grouping No Yes
Creation time embedded No Approximate time
Easy library support Excellent Increasing rapidly
Good for generic IDs Yes Yes
Useful for time-heavy workloads Possible Often attractive
Predictable sequence No Time component is observable

Neither is universally better.

They optimize for slightly different priorities.

One subtle limitation: the same millisecond

It is tempting to describe UUID v7 as:

perfectly ordered by creation time

That is not quite correct.

UUID v7 includes a millisecond timestamp.

If several UUIDs are generated during the same millisecond, the timestamp portion can be identical.

Unless the implementation adds a monotonic strategy, their relative ordering inside that millisecond is not guaranteed to represent exact creation order.

So a safer description is:

UUID v7 provides time grouping across milliseconds.

If strict ordering matters, use an explicit timestamp or sequence designed for that requirement.

UUID v7 exposes time information

There is another tradeoff.

UUID v4 does not encode its creation timestamp.

UUID v7 does.

That means someone inspecting a UUID v7 can derive an approximate generation time from it.

For most application IDs, that may be completely acceptable.

But it matters if hiding creation time is part of your threat model.

For example, you may not want publicly exposed identifiers to reveal when a sensitive resource was created.

Again:

Choose an identifier based on your requirements, not because one version is newer.

What about database primary keys?

This is where the debate becomes interesting.

For a new application, you might be choosing between:

BIGINT auto increment
UUID v4
UUID v7
Enter fullscreen mode Exit fullscreen mode

Each has advantages.

Auto-incrementing integers

Advantages:

  • compact
  • naturally ordered
  • excellent database support
  • easy to debug

Tradeoffs:

  • usually database-generated
  • require coordination
  • expose simple sequence information when public

UUID v4

Advantages:

  • decentralized
  • mature
  • unpredictable
  • easy to generate almost anywhere

Tradeoffs:

  • random index distribution
  • no time information
  • larger than common integer IDs

UUID v7

Advantages:

  • decentralized
  • time-grouped
  • UUID-compatible
  • often friendlier to ordered workloads

Tradeoffs:

  • exposes approximate creation time
  • newer ecosystem support
  • not strictly ordered within every millisecond

There is no universal winner.

Store UUIDs properly

Another performance mistake has nothing to do with the UUID version.

It is how the UUID is stored.

A UUID is 128 bits.

Its human-readable representation contains 36 characters:

550e8400-e29b-41d4-a716-446655440000
Enter fullscreen mode Exit fullscreen mode

But storing every UUID as a generic text field is not always necessary.

Many databases provide dedicated UUID types.

For example, PostgreSQL supports:

CREATE TABLE users (
    id UUID PRIMARY KEY
);
Enter fullscreen mode Exit fullscreen mode

Using the database's native UUID type can provide clearer semantics and more efficient storage than treating identifiers as arbitrary strings.

Always check what your database supports.

When I would choose UUID v4

UUID v4 remains a good choice when:

  • you want maximum ecosystem compatibility
  • random identifiers are desirable
  • your current system already uses v4
  • write ordering is not a concern
  • you do not want the ID to encode creation time
  • your database workload already performs well

There is little reason to migrate a working application from v4 solely because v7 exists.

When I would choose UUID v7

For a new application, I would seriously consider UUID v7 when:

  • records are frequently inserted
  • time grouping is useful
  • IDs are stored in indexed database columns
  • multiple services generate identifiers
  • you want sortable UUID-style identifiers
  • exposing approximate creation time is acceptable

This is particularly interesting for systems dealing with large chronological datasets.

Think:

events
messages
orders
logs
audit records
transactions
Enter fullscreen mode Exit fullscreen mode

Don't use UUIDs as secrets

This deserves repeating.

Neither UUID v4 nor UUID v7 should replace proper secrets.

Do not treat a UUID as equivalent to:

  • an API key
  • session token
  • password-reset token
  • authentication token
  • authorization rule

Even when an identifier is difficult to guess, your application should still enforce access control.

Use cryptographically appropriate tokens for security-sensitive purposes.

Try both versions

Sometimes the easiest way to understand the difference is simply to generate both.

You can compare UUID v4 and v7 using the Genory UUID Generator.

Generate several v4 values and notice how unrelated they appear.

Then generate several v7 values and compare identifiers created at different times.

Genory also exposes UUID generation through its developer API. For supported API access, the current documentation is available at genory.dev/docs.

Conceptually, the API supports choosing the UUID version:

version = v4
Enter fullscreen mode Exit fullscreen mode

or:

version = v7
Enter fullscreen mode Exit fullscreen mode

That makes it easy to test how both identifier strategies behave in your own fixtures before making an architectural decision.

So which one should you use in 2026?

For an existing system successfully using UUID v4:

Keep using v4 unless you have a concrete reason to change.

For a new application where UUIDs will become heavily indexed database keys:

UUID v7 deserves serious consideration.

For identifiers where you do not want to reveal approximate creation time:

UUID v4 may be preferable.

For systems where chronological grouping is useful:

UUID v7 is often the more interesting choice.

The most important rule is not:

Always use the newest UUID version.

It is:

Understand what information your identifier contains and how your storage system will use it.

Final thought

UUID v4 solved an important distributed-systems problem extremely well.

UUID v7 does not replace it.

Instead, v7 adds something many modern applications can benefit from: time-aware ordering without giving up decentralized UUID generation.

That makes the decision surprisingly simple:

Use v4 when randomness is exactly what you need.

Use v7 when time grouping gives your system an advantage.

And if performance is the reason you're choosing between them, benchmark your own database instead of trusting a rule of thumb.

Top comments (0)