Developer Tools

UUID v4 vs UUID v7: Which One Should You Use?

A definitive guide for developers comparing UUID v4 and UUID v7. Learn the differences in generation, database indexing performance, collision probability, and which to choose for modern applications.

Published: July 22, 2026
23 min read
UUID v4 vs UUID v7: Which One Should You Use?

When building modern web applications, distributed systems, or cloud-native microservices, one of the most critical foundational decisions you must make is how to identify your records. For decades, developers have debated the merits of auto-incrementing integers versus universally unique identifiers (UUIDs). While the industry has largely shifted towards UUIDs for their undeniable benefits in distributed architectures, a new debate has emerged: UUID v4 vs UUID v7.

Choosing the right UUID version is no longer a trivial matter of picking a random string generator. It is a decision that deeply impacts your database indexing performance, storage efficiency, API design, and system scalability. With the formalization of RFC 9562, UUID v7 has burst onto the scene, promising to solve the notorious performance bottlenecks associated with the purely random UUID v4.

But does this mean UUID v4 is entirely obsolete? Should you immediately migrate your legacy systems to UUID v7? In this comprehensive guide, we will unpack the engineering principles behind these two standards. We will explore how they are constructed, dissect their impact on database operations like B-tree clustering, and provide you with actionable decision frameworks so you can choose the optimal identifier for your specific use cases.

What Is a UUID?

A Universally Unique Identifier (UUID)—sometimes referred to as a Globally Unique Identifier (GUID) in the Microsoft ecosystem—is a 128-bit label used for information in computer systems. When generated according to standard methods, UUIDs are, for practical purposes, unique. Their uniqueness does not depend on a central registration authority or coordination between the parties generating them.

Why Do We Need UUIDs?

Traditionally, applications relied on auto-incrementing integers (e.g., 1, 2, 3...) generated by relational databases like PostgreSQL, MySQL, or SQL Server. While auto-incrementing IDs are simple, compact, and perform brilliantly for local, monolithic databases, they introduce significant architectural friction in modern distributed environments:

  1. Coordination Bottlenecks: In distributed architectures with multiple database nodes or active-active replication, ensuring that two nodes do not issue the same integer ID requires complex locking mechanisms or coordination, which degrades write performance.
  2. Offline Generation: Mobile applications or offline-first clients often need to create records locally and sync them later. Without a guaranteed unique ID, the client must wait for the server to assign an ID, breaking offline functionality.
  3. Security and Predictability: Auto-incrementing IDs expose your growth metrics. If a competitor signs up and receives user ID 1500, and creates another account a week later and gets 2000, they know exactly how many users you acquired. They also open the door to Insecure Direct Object Reference (IDOR) attacks, where a malicious user might iterate through user IDs (/api/users/1, /api/users/2) to scrape data.

UUIDs solve these problems elegantly. Because the pool of possible UUIDs is astronomically large (there are $2^122$ possible v4 UUIDs), different systems can independently generate IDs without any central coordinator, secure in the mathematical near-impossibility of a collision.

The UUID Format

A standard UUID is a 128-bit value, typically represented as a 36-character string consisting of 32 hexadecimal digits and four hyphens, broken into five groups in a 8-4-4-4-12 format.

Here is an example of a UUID string representation: 123e4567-e89b-12d3-a456-426614174000

Despite this human-readable string representation, it is crucial to remember that a UUID is fundamentally just a 16-byte binary number. How those 128 bits are calculated depends entirely on the version of the UUID being generated.

UUID Versions Explained

Over the years, the UUID standard has evolved to accommodate different use cases, culminating in the recent RFC 9562 update. Here is a quick overview of the UUID landscape:

  • UUID v1 (Time and MAC-based): Generates IDs using the computer's MAC address and the current timestamp. It is sortable but exposes identifiable hardware information, leading to privacy concerns.
  • UUID v2 (DCE Security): Similar to v1 but includes local domain identifiers (like POSIX UIDs). It is rarely used in practice today.
  • UUID v3 (Name-based, MD5): Generates a deterministic UUID based on a namespace and a unique name, hashed using an MD5 Hash Generator. If you input the same namespace and name, you always get the exact same UUID.
  • UUID v4 (Random): The most popular version. It is generated using a secure random number generator. It contains no metadata about the machine or the time.
  • UUID v5 (Name-based, SHA-1): The same concept as v3, but uses the more secure SHA-1 hashing algorithm instead of MD5.
  • UUID v6 (Time-based, Sortable): A recent addition introduced in RFC 9562. It reshuffles the timestamp bits of v1 to allow for database sortability, but still relies on MAC addresses or random node IDs.
  • UUID v7 (Time-ordered, Random): The modern solution. It combines a high-precision Unix timestamp with random data, providing chronological sortability and eliminating the B-tree fragmentation problems of v4, without exposing MAC addresses.
  • UUID v8 (Custom): An experimental format reserved for vendor-specific or entirely custom UUID implementations that do not fit into the other definitions.

In modern backend development, the primary choice almost always boils down to UUID v4 for pure randomness versus UUID v7 for time-based, database-friendly sortability.

What Is UUID v4?

UUID version 4 is the undisputed heavyweight champion of the UUID world. For the better part of two decades, if a developer said they were using a "UUID," it was almost guaranteed they were referring to UUID v4.

How UUID v4 Works

UUID v4 is fundamentally defined by one characteristic: pure, unadulterated randomness. Out of the 128 bits that make up the identifier, 122 bits are entirely randomly generated using a Cryptographically Secure Pseudorandom Number Generator (CSPRNG).

The remaining 6 bits are reserved for version and variant metadata. Specifically, the 13th hexadecimal character is always 4 (indicating version 4), and the 17th character is always 8, 9, a, or b (indicating the standard variant).

Example UUID v4: f47ac10b-58cc-4372-a567-0e02b2c3d479

Entropy and Collision Probability

Because UUID v4 relies on randomness, a common concern among newer developers is the risk of a "collision"—generating the exact same ID twice.

To understand why this is practically impossible, we must look at the entropy. UUID v4 provides 122 bits of randomness, meaning there are $2^122$ (or roughly $5.3 \times 10^36$) possible identifiers. To put that staggering number into perspective: you would need to generate 1 billion UUIDs per second for about 85 years before you reached a 50% probability of a single collision occurring.

For any realistic web application, the chance of a UUID v4 collision is effectively zero. Your database server is vastly more likely to be destroyed by a meteorite than it is to experience a UUID v4 collision.

Advantages of UUID v4

  1. Simplicity: It is trivial to generate. Almost every programming language has a built-in library for creating v4 UUIDs.
  2. Unpredictability: Because the bits are purely random, UUID v4 is fantastic for security tokens, password reset links, or API keys where you absolutely cannot allow an attacker to guess the next valid identifier.
  3. Anonymity: It leaks zero metadata. You cannot determine when a v4 UUID was created or which machine created it.

Limitations of UUID v4

The fatal flaw of UUID v4 lies entirely in how relational databases store data on disk. Because every new UUID is completely random, it can cause severe performance degradation when used as a primary key, a phenomenon we will explore deeply in the Database Performance Comparison section.

What Is UUID v7?

UUID version 7 is the modern successor designed to solve the structural flaws of UUID v4. Formalized in RFC 9562 (published in May 2024), UUID v7 represents a paradigm shift in how we generate distributed identifiers.

How UUID v7 Works

Instead of relying purely on randomness, UUID v7 is a hybrid format. It seamlessly blends a highly precise Unix timestamp with cryptographically secure random data.

The 128 bits are divided logically:

  1. Timestamp (48 bits): A Unix timestamp representing milliseconds since the Unix Epoch (January 1, 1970). This guarantees that IDs generated later in time will have a higher binary value than IDs generated earlier. (If you need to manually inspect or convert these embedded timestamps, our free Timestamp Converter is incredibly useful).
  2. Version & Variant (6 bits): Metadata indicating it is a version 7 UUID. The 13th character will always be 7.
  3. Randomness (74 bits): Cryptographically secure random data to ensure uniqueness, even if millions of IDs are generated in the exact same millisecond.

Example UUID v7: 018e9b81-3444-7123-a554-890203f1b402 (Notice the 018... prefix, which is characteristic of current UUID v7s, representing the recent Unix timestamp).

Why Was UUID v7 Introduced?

The industry needed a solution that offered the distributed generation benefits of UUID v4, without sacrificing the database locality and performance benefits of sequential auto-incrementing integers. UUID v1 and v6 attempted to solve this but introduced privacy concerns by embedding MAC addresses.

UUID v7 hits the perfect sweet spot: it is completely anonymous (no MAC addresses), highly resistant to collisions (thanks to 74 bits of random entropy), and most importantly, it is lexicographically sortable by creation time.

Advantages of UUID v7

  1. Chronological Sortability: Because the most significant 48 bits are a timestamp, sorting UUID v7s naturally sorts the records by their creation time. This often eliminates the need for a separate created_at index in your database.
  2. Massive Database Performance Gains: By generating sequential IDs, UUID v7 prevents B-tree index fragmentation, dramatically speeding up INSERT operations and improving cache hit rates for SELECT queries.
  3. Built-in Timestamps: You can extract the exact millisecond a UUID v7 was generated directly from the ID itself, without querying a database.

Generate UUID v4 and UUID v7 Instantly

Need test data? Create RFC-compliant UUIDs, bulk generate identifiers, and compare formats with the free Vyrobox UUID Generator.

UUID v4 vs UUID v7: The Ultimate Comparison

To make the best architectural decision, you must understand how these two standards stack up across various technical dimensions.

FeatureUUID v4UUID v7
Primary Mechanism122 bits of pure CSPRNG randomness48-bit timestamp + 74 bits of randomness
SortabilityNone (Completely random)Excellent (Chronologically sortable)
Database LocalityTerrible (Causes index fragmentation)Excellent (Sequential inserts)
Information LeakageNoneLeaks creation time (millisecond precision)
PredictabilityUnpredictable (Secure)Partially predictable (Time is known)
Collision ProbabilityAstronomically lowAstronomically low
Primary Key SuitabilityPoor (for large datasets)Excellent
API Token SuitabilityExcellentPoor (Avoid predictable tokens)
Storage Size16 bytes (128 bits)16 bytes (128 bits)
StandardizationRFC 4122 / RFC 9562RFC 9562

Let's break down the most critical differences.

Randomness vs Time-Ordering

UUID v4 is a true scattershot approach. If you generate ten v4 UUIDs in a row, their values will have zero correlation.

UUID v7 is heavily structured around time. If you generate ten v7 UUIDs sequentially, the first 48 bits (the timestamp) will be identical or sequentially higher, while only the final 74 bits will change randomly.

Predictability and Security

Because UUID v4 is purely random, it is impossible to guess the next ID in a sequence. This makes it ideal for security contexts. If you use a UUID v4 for an email verification link or a password reset token, attackers have zero leverage to guess valid tokens.

UUID v7, on the other hand, is partially predictable. If an attacker knows that a record was created at 2024-05-01 12:00:00, they immediately know the first 48 bits of that UUID. While they still have to guess the 74 random bits (which is computationally infeasible), exposing the creation time might be a security or business risk in highly sensitive contexts. Therefore, UUID v7 should not be used for API keys, secret tokens, or cryptographic nonces.

Database Performance Comparison

To truly understand why developers are flocking to UUID v7, we must look under the hood of relational database management systems like PostgreSQL, MySQL (InnoDB), and SQL Server.

The Problem with Random UUIDs (UUID v4)

Most relational databases organize tables and indexes using a data structure called a B-tree (specifically a B+ tree).

When you use an auto-incrementing integer or a UUID v7 as a primary key, new records are sequentially added to the right-most edge of the B-tree. The database simply appends the data, ensuring that database pages are filled efficiently.

When you use a random UUID v4 as a primary key, the database is forced to insert the new record into a random location within the B-tree. This causes several severe performance bottlenecks:

  1. Page Splits: As data is inserted randomly, database memory pages fill up unevenly. When a page becomes full and a new random ID needs to be inserted into that specific page, the database must pause, split the page into two, and reorganize the tree. This is extremely computationally expensive and slows down write performance heavily on write-intensive workloads.
  2. Index Fragmentation: Continuous random inserts leave empty gaps in database pages, leading to a bloated, fragmented index that consumes significantly more disk space and RAM than necessary.
  3. Cache Misses: Databases rely heavily on keeping the most active data in fast RAM. With sequential IDs, the "hot" active page is small and stays in RAM. With random IDs, every insert touches a different, random page on disk, forcing the database to constantly swap pages in and out of memory, destroying cache efficiency and causing massive disk I/O thrashing.

The UUID v7 Solution

Because UUID v7 begins with a timestamp, it behaves almost exactly like an auto-incrementing integer from the database's perspective.

When you insert a UUID v7, the database engine recognizes that the new value is lexicographically greater than previous values. It appends the new record to the end of the B-tree.

The result?

  • Zero unnecessary page splits.
  • Highly packed, unfragmented indexes.
  • Excellent memory cache locality, as recent inserts all land on the same "hot" memory pages.

In benchmarks comparing MySQL InnoDB INSERT performance on tables with tens of millions of rows, switching from a random UUID v4 to a time-ordered UUID v7 can result in 3x to 5x faster write throughput, while significantly reducing server CPU and disk I/O load.

When Should You Use UUID v4?

Despite the database performance drawbacks, UUID v4 remains an essential tool in a backend engineer's arsenal. You should choose UUID v4 when:

  • You are generating security tokens: Password reset links, email verification codes, or short-lived session identifiers must be completely unpredictable. UUID v4 is the industry standard for this.
  • You need absolute anonymity: If your identifier must not leak any metadata (like when the record was created) to external users or competitors.
  • You are building stateless API keys: Generating random API keys requires maximum entropy.
  • Database indexing is not a bottleneck: For small tables, configuration files, or low-write-volume applications, the performance hit of a random B-tree insert is negligible. If your table will never exceed 100,000 rows, optimizing for UUID v7 might be premature optimization.
  • Working with legacy constraints: If you are bound by an older ecosystem that strictly validates UUIDs specifically for the v4 format (e.g., rigid regex checks).

When Should You Use UUID v7?

UUID v7 should be considered the default choice for almost all new database entity identifiers. You should choose UUID v7 when:

  • It is a Primary Key in a Database: This is the killer feature. Whether you are using PostgreSQL, MySQL, SQLite, or CockroachDB, UUID v7 will dramatically optimize your clustered indexes and write performance for entities like Users, Orders, Posts, or Invoices.
  • You have write-heavy workloads: Applications like event logs, audit trails, time-series data, or IoT sensor ingestion require maximum INSERT throughput. UUID v7 prevents page splits during high-volume ingestion.
  • You need chronological sorting: When paginating through an API (e.g., "Give me the next 50 messages"), you can paginate directly on the UUID v7 primary key via cursor-based pagination, entirely eliminating the need for a separate index on a created_at timestamp column.
  • Microservices architecture: When generating IDs locally in decentralized services before saving them to a central database, UUID v7 ensures those IDs will sort correctly across the entire system.

Code Examples

Generating UUIDs is straightforward in most modern programming languages. Here is how you can generate both versions across popular backend ecosystems.

Note: Because UUID v7 is relatively new (RFC 9562 was finalized in 2024), some standard libraries do not support it natively yet, requiring lightweight third-party packages.

JavaScript / TypeScript (Node.js & Browser)

The ubiquitous uuid npm package supports both.

import { v4 as uuidv4, v7 as uuidv7 } from 'uuid';

// Generate UUID v4
const randomId = uuidv4();
console.log(`UUID v4: ${randomId}`);

// Generate UUID v7
const timeOrderedId = uuidv7();
console.log(`UUID v7: ${timeOrderedId}`);

Python

Python's built-in uuid module supports v4 natively. For v7, you should use the uuid-utils or uuid6 package.

import uuid
import uuid6 # pip install uuid6

# Generate UUID v4
random_id = uuid.uuid4()
print(f"UUID v4: {random_id}")

# Generate UUID v7
time_ordered_id = uuid6.uuid7()
print(f"UUID v7: {time_ordered_id}")

Go (Golang)

The popular google/uuid package supports v7 as of version 1.6.0.

package main

import (
	"fmt"
	"github.com/google/uuid" // go get github.com/google/uuid
)

func main() {
	// Generate UUID v4
	randomId := uuid.New()
	fmt.Printf("UUID v4: %s\n", randomId.String())

	// Generate UUID v7
	timeOrderedId, _ := uuid.NewV7()
	fmt.Printf("UUID v7: %s\n", timeOrderedId.String())
}

Rust

The standard uuid crate natively supports v7 if you enable the v7 feature flag.

# Cargo.toml
[dependencies]
uuid = { version = "1.8", features = ["v4", "v7", "fast-rng"] }
use uuid::Uuid;

fn main() {
    // Generate UUID v4
    let random_id = Uuid::new_v4();
    println!("UUID v4: {}", random_id);

    // Generate UUID v7
    let time_ordered_id = Uuid::now_v7();
    println!("UUID v7: {}", time_ordered_id);
}

Test UUID Sorting and Generation

Need to verify how a UUID v7 sorts lexicographically? Use our free generator to create bulk UUIDs instantly.

UUID v4 vs ULID vs Nano ID

While UUIDs are the standard, the developer ecosystem has created alternative identifier formats over the years to solve the exact problems UUID v7 now addresses. It is worth comparing them.

FeatureUUID v7ULIDNano ID
Format36 chars (Hex string with hyphens)26 chars (Crockford's Base32)Customizable (Default 21 chars URL-safe)
SortabilityYes (Timestamp based)Yes (Timestamp based)No (Pure random)
StandardizedYes (IETF RFC 9562)No (Community Spec)No (Community Spec)
Database PerformanceExcellentExcellentPoor (Same as UUID v4)
ReadabilityLowHigh (No hyphens, shorter)High (Short, URL friendly)
Native DB SupportHigh (UUID column types in Postgres)Low (Requires VARCHAR(26) or conversion)Low (Requires VARCHAR)

ULID (Universally Unique Lexicographically Sortable Identifier) was a popular community alternative to UUID v4 for many years because it provided time-ordering before UUID v7 existed. However, with the official ratification of UUID v7 in RFC 9562, the industry is largely consolidating back to the official UUID standard. UUID v7 benefits from native 16-byte binary database column types (UUID in Postgres), whereas ULID often forces developers to store strings or write custom binary conversion logic.

Nano ID is fantastic for URL-friendly, short, random identifiers (like a YouTube video ID). It is a direct competitor to UUID v4, not v7, as it lacks time-ordering.

Common Myths

"UUID v7 is less secure than UUID v4."

Misleading. UUID v7 provides 74 bits of cryptographically secure random entropy. While technically less than v4's 122 bits, 74 bits is still astronomically large. You would need to generate trillions of IDs in the exact same millisecond to even approach a negligible risk of collision. However, v7 is less "secure" only in the sense that it leaks the timestamp, making it unsuitable for secret API tokens.

"Sequential IDs are always better than random IDs."

False. Sequential IDs are strictly better for database clustered index performance. They are actively harmful for security tokens, session IDs, or any context where unpredictability prevents enumeration attacks.

"UUIDs always destroy database performance."

False. This myth stems entirely from the misuse of UUID v4 as a primary key in massive tables. By using UUID v7, you achieve the distributed generation benefits of a UUID with the identical B-tree locality performance of a traditional auto-incrementing integer.

Migration Guide: Moving from v4 to v7

If you have an existing production database using UUID v4 for primary keys, you might be wondering if you should migrate.

Should You Migrate?

For existing, stable tables: Probably not. If your application is running fine and database I/O is not a bottleneck, migrating millions of existing UUID v4 rows to v7 is a monumental, risky effort that offers zero immediate user-facing value. Re-writing primary keys requires cascading updates across all foreign keys, which requires significant downtime.

For new tables in an existing database: Yes, absolutely. There is no rule stating a database must exclusively use one UUID version.

Can v4 and v7 Coexist?

Yes. Because a UUID is ultimately just a 16-byte binary sequence, databases do not care about the internal version structure. You can store a UUID v4 and a UUID v7 in the exact same PostgreSQL UUID column.

This means your migration strategy can be entirely forward-looking:

  1. Update your application code to generate UUID v7 for all new records.
  2. Leave existing records as UUID v4.
  3. Your API and database will continue to function seamlessly, but all future database inserts will benefit from sequential B-tree performance.

Best Practices for Using UUIDs

To extract maximum performance and reliability from your identifiers, adhere to these engineering best practices:

1. Store UUIDs Efficiently

Never store a UUID as a VARCHAR(36) in a relational database if you can avoid it.

  • PostgreSQL: Always use the native UUID column type. It stores the data optimally as a 16-byte binary value while presenting it as a string to your application.
  • MySQL: If using MySQL 8.0+, utilize the UUID_TO_BIN() and BIN_TO_UUID() functions to store the identifier as a BINARY(16) column. A VARCHAR(36) takes more than twice the storage space and dramatically slows down index lookups.
  • SQL Server: Use the UNIQUEIDENTIFIER column type.

2. Extract Timestamps Safely

Because UUID v7 contains a Unix timestamp, you can theoretically extract the creation time in your application code, avoiding the need for a separate created_at database column. While this saves space, be cautious: if your system allows users to explicitly provide their own UUIDs during an API import, they could forge the timestamp, creating historical discrepancies in your data.

3. API Design

When returning UUIDs in JSON APIs, always serialize them using the standard 36-character hyphenated lowercase string representation (e.g., 018e9b81-3444-7123-a554-890203f1b402). Do not return binary formats, base64 encodings, or hyphenless strings, as this breaks ecosystem compatibility with standard parsing libraries.

4. Validation

If your API endpoint expects a UUID v7, validate that the incoming string is not only a valid UUID, but specifically version 7. Relying purely on regex length checks can result in unexpected behavior if a client submits a v4 ID when your system expects time-ordered data.

Common Mistakes to Avoid

  1. Using UUID v1 or v6: Unless you have incredibly specific legacy constraints, do not use versions that leak MAC addresses. The privacy risks are rarely worth it.
  2. Generating UUIDs in the database: While you can use functions like uuid_generate_v4() in PostgreSQL, generating the UUID in your backend application layer is generally superior. It removes load from the database CPU and allows your application to know the ID of an object before the database transaction even begins.
  3. Using UUID v7 for API Keys: As mentioned, exposing the exact creation millisecond of an API key is an unnecessary information leak. Stick to UUID v4 or high-entropy random byte strings for secrets.

Frequently Asked Questions

Which UUID version should new projects use?

For database primary keys, you should almost exclusively use UUID v7. For security tokens or random generation, use UUID v4.

Is UUID v7 an official standard?

Yes. It was officially standardized by the IETF in RFC 9562, published in May 2024.

Can UUID v4 collide?

Theoretically, yes. Practically, no. You would need to generate billions of IDs per second for decades to reach a statistical probability of a collision.

Is UUID v7 faster than UUID v4?

In terms of generation speed in application code, they are virtually identical. In terms of database insert performance, UUID v7 is significantly faster because its time-ordered nature prevents index fragmentation.

Can databases sort UUID v7?

Yes. Because the first 48 bits represent a sequential timestamp, any standard database ORDER BY id ASC query will naturally sort the records chronologically.

Can PostgreSQL generate UUID v7?

PostgreSQL natively supports the UUID data type, but native generation of v7 via a built-in function (like gen_random_uuid() for v4) requires PG 17+. However, you should generally generate UUIDs in your application code anyway.

Is UUID v7 secure?

It is cryptographically secure against collisions, but it is not "secure" against predictability, because it intentionally embeds a public timestamp.

Should I replace UUID v4 with ULID?

No. With the release of the official RFC 9562 standard, UUID v7 provides the exact same benefits as ULID but with native database binary support and broader standardized ecosystem tooling.

Conclusion

The debate between UUID v4 vs UUID v7 represents a significant milestone in modern software engineering. For years, developers accepted the database performance penalties of UUID v4 as a necessary trade-off for the architectural freedom of distributed generation.

With UUID v7, that compromise is officially over.

By elegantly combining a high-precision timestamp with robust cryptographically secure randomness, UUID v7 provides the best of both worlds. It delivers the sequential B-tree clustering performance of an auto-incrementing integer, while maintaining the collision resistance and distributed generation capabilities of a universally unique identifier.

Your engineering decision matrix is now remarkably simple: If you need an identifier for a database entity, a primary key, or an event log, choose UUID v7. If you need an unpredictable, anonymous identifier for a security token or a stateless API key, choose UUID v4.

Start Generating UUIDs Today

Ready to implement UUIDs in your next project? Use the Vyrobox UUID Generator to instantly create RFC-compliant v4 and v7 identifiers for your applications.

Tags:uuid v4 vs uuid v7uuid v4uuid v7uuid version 4uuid version 7uuid generatoruuid for databasesuuid best practices
Share:

Subscribe to our Newsletter

Get the latest tutorials, tips, and free tool updates delivered directly to your inbox. No spam, ever.