Modern applications need reliable ways to identify users, transactions, files, API requests, database records, and events. In small systems, an auto-incrementing integer may be enough. In distributed applications, however, relying on a central database sequence can create unnecessary coordination and limit scalability.
Universally Unique Identifiers, commonly known as UUIDs, solve this problem by allowing applications to generate identifiers independently. A service can create an ID before storing a record, publishing an event, or communicating with another system.
UUID v4 has been the most familiar option for years, but UUID v7 is increasingly attractive for database-heavy and time-oriented applications. Both formats provide globally unique 128-bit identifiers, but they differ in generation method, ordering, privacy characteristics, and database behavior.
This guide explains the practical differences between UUID v4 and UUID v7 and helps developers choose the right version for a modern software project.
Table of Contents
What Is a UUID?
A UUID is a 128-bit identifier designed to be unique across systems without requiring a central issuing authority. It is usually represented as a hexadecimal string divided into five groups.
550e8400-e29b-41d4-a716-446655440000
UUIDs are frequently used for:
- database primary keys;
- API resource identifiers;
- event and message IDs;
- distributed tracing;
- file and object references;
- user and session records;
- test-data generation;
- records created by multiple independent services.
The UUID version determines how the identifier is constructed. UUID v4 relies primarily on randomness, while UUID v7 combines a timestamp with random data.
How UUID v4 Works
UUID v4 is generated from random or pseudo-random values. Several bits are reserved to indicate the UUID version and variant, while most of the remaining bits provide randomness.
Example UUID v4:
1d48dc72-9182-45a0-bd6e-71c0df751f4a
The4at the beginning of the third group identifies the value as UUID v4.
Advantages of UUID v4
- Broad compatibility:ย UUID v4 is supported by nearly every major programming language, framework, database, and operating system.
- Independent generation:ย Services can generate identifiers without contacting a central database.
- No timestamp exposure:ย The identifier does not directly reveal when it was generated.
- Simple implementation:ย Most platforms include a standard UUID v4 function.
- Very low collision probability:ย Correctly generated values are extremely unlikely to collide.
Limitations of UUID v4
The main drawback of UUID v4 is its random ordering. When random UUIDs are used as indexed database keys, new records may be inserted throughout the index rather than near its end.
Depending on the database engine and workload, this can result in:
- additional B-tree page splits;
- reduced cache locality;
- greater index fragmentation;
- less predictable record ordering;
- more random input and output activity.
These effects may be negligible in a small application, but they can become more important in large tables with frequent inserts.
How UUID v7 Works
UUID v7 uses a Unix timestamp in the leading portion of the identifier and combines it with random data. Because the timestamp appears first, UUID v7 values sort approximately in the order they were created.
Example UUID v7:
0197c395-a729-7d0f-ae93-38708de981a4
The7at the beginning of the third group indicates UUID v7.
Advantages of UUID v7
- Chronological sorting:ย Newer UUIDs generally sort after older ones.
- Better index locality:ย Sequentially generated values tend to be inserted near one another in a database index.
- Distributed generation:ย Applications do not need a central sequence service.
- Useful for time-oriented data:ย UUID v7 is well suited to events, logs, transactions, and audit records.
- Familiar UUID format:ย It remains compatible with systems that store standard 128-bit UUID values.
Limitations of UUID v7
- Library and framework support is newer than UUID v4 support.
- The identifier reveals an approximate creation time.
- Clock synchronization may affect ordering across multiple machines.
- Older validators may reject UUID v7 even when the value is valid.
UUID v4 vs UUID v7 at a Glance
Developers can inspect generated values and review a practical comparison of UUID v4 and UUID v7 before deciding which format is more appropriate for their application.
| Feature | UUID v4 | UUID v7 |
|---|---|---|
| Generation basis | Random data | Timestamp and random data |
| Chronological sorting | No | Yes, approximately |
| Creation time encoded | No | Yes |
| Database index locality | Usually weaker | Usually better |
| Ecosystem support | Excellent | Growing |
| Distributed generation | Yes | Yes |
| Good for public identifiers | Yes | Yes, with timestamp considerations |
| Good for event ordering | Limited | Better |
Database Performance Considerations
Database behavior is one of the strongest reasons to consider UUID v7.
Many databases use B-tree indexes for primary keys. A B-tree works efficiently when new values are inserted near the end of the index. Auto-incrementing integers naturally follow this pattern because every new value is larger than the previous one.
UUID v4 values are random, so inserts may occur at many different points in the index. Under heavy write loads, this can produce more page splits and reduce cache efficiency.
UUID v7 values contain a timestamp prefix. Identifiers generated at similar times are therefore grouped together, which normally creates a more sequential insertion pattern.
This does not mean UUID v7 will always produce a dramatic performance improvement. The result depends on:
- database engine;
- table size;
- insert volume;
- available memory;
- index configuration;
- storage hardware;
- batching strategy;
- the number of secondary indexes.
Teams should benchmark both approaches with realistic data and workloads rather than relying on a fixed performance claim.
Storage Recommendations
A UUID is often displayed as a 36-character string, but storing it as ordinary text is not always the most efficient approach.
Where possible, use a native UUID database type or a 16-byte binary representation.
- PostgreSQL provides a native
uuidtype. - MySQL can store UUIDs using
BINARY(16). - SQL Server provides the
uniqueidentifiertype.
Native or binary storage generally requires less space than a character column and may improve index efficiency.
Applications should also standardize the external representation. For example, decide whether UUIDs will always be lowercase and whether hyphens are mandatory. Consistent formatting simplifies validation, logging, testing, and API documentation.
Privacy and Security Considerations
UUID v4 does not directly reveal when the identifier was created. This can be useful for public API resources, customer records, and URLs where timestamp exposure is undesirable.
UUID v7 contains a timestamp. Anyone who receives the value may be able to estimate when it was generated. That is often acceptable for internal records, logs, event streams, and database keys, but it should be considered when IDs are publicly exposed.
Neither UUID version should be treated as an authorization mechanism. A UUID may be difficult to guess, but it is still only an identifier.
Applications must continue to enforce:
- authentication;
- authorization;
- resource ownership checks;
- rate limiting;
- input validation;
- secure token handling.
Sensitive actions should never be protected only by an unpredictable-looking URL.
UUIDs in APIs
UUIDs are widely used as resource identifiers in REST and GraphQL APIs.
GET /api/orders/0197c395-a729-7d0f-ae93-38708de981a4
Using UUIDs allows an application to generate the final identifier before the record reaches the database. This can simplify asynchronous workflows and distributed processing.
API documentation should specify:
- which UUID version is expected;
- whether clients may generate identifiers;
- the accepted textual format;
- whether hyphens are required;
- how invalid identifiers are handled;
- whether IDs are case-sensitive.
Most JSON APIs transmit UUIDs as strings because JSON does not have a native UUID type.
{
"id": "0197c395-a729-7d0f-ae93-38708de981a4",
"status": "created",
"createdAt": "2026-06-28T14:32:11Z"
}
UUIDs in Distributed Systems
Distributed systems benefit from identifiers that can be generated independently.
Consider an application with separate order, payment, inventory, and notification services. The order service can generate a UUID before saving the order, include it in an event, and pass it to every downstream service.
This removes the need to request an ID from a central database before other processing can begin.
UUID v4 works well when only uniqueness is important. UUID v7 adds approximate chronological ordering, which can make records easier to inspect, paginate, and process.
However, UUID v7 should not replace an explicit timestamp or message sequence when exact ordering is required. Concurrent generation, clock differences, and asynchronous delivery can still cause events to be processed in a different order.
UUIDs for Logs and Distributed Tracing
UUIDs are also useful as request and correlation identifiers.
When a request enters an application, the system can generate a UUID and include it in every log entry produced by the API gateway, application service, message worker, and database process.
request_id=0197c395-a729-7d0f-ae93-38708de981a4
service=payment-api
status=completed
duration_ms=184
This gives developers a common value they can use to trace one request through multiple systems.
UUID v4 provides privacy-friendly randomness. UUID v7 may make logs easier to sort because newer values are generally larger than older ones.
UUID v7 in Event-Driven Applications
Event-driven systems frequently need unique event identifiers. An event producer can generate a UUID before publishing a message to Kafka, RabbitMQ, or another message broker.
Consumers can store the event ID and use it to detect duplicate deliveries. This is important in systems that use at-least-once delivery, where a message may occasionally be processed more than once.
UUID v7 is particularly suitable for event records because:
- events are usually time-oriented;
- new identifiers sort approximately by creation time;
- producers can generate IDs independently;
- the values can still be stored in standard UUID columns.
An explicit event timestamp should still be stored separately for reporting, auditing, and exact time-based queries.
Collision Probability
Both UUID v4 and UUID v7 are designed to make accidental collisions extremely unlikely.
UUID v4 obtains its uniqueness primarily from random data. UUID v7 obtains it from the combination of a timestamp and random bits. Multiple identifiers generated during the same millisecond remain distinct because their random portions differ.
Applications should still enforce a primary-key or unique constraint in the database. This protects the system from duplicates caused by:
- incorrect implementations;
- weak random generators;
- data-import errors;
- application bugs;
- manually supplied identifiers.
A UUID library reduces the probability of implementation mistakes and should normally be preferred over custom generation code.
Clock Behavior in UUID v7
Because UUID v7 contains a timestamp, system clock behavior deserves attention.
If two servers have significantly different clock settings, UUIDs generated by one server may sort before or after values produced at the actual corresponding time on another server.
Infrastructure teams should keep clocks synchronized with a reliable time service. Applications that require strict ordering should use additional mechanisms such as:
- database timestamps;
- message offsets;
- sequence numbers;
- logical clocks;
- transaction ordering.
UUID v7 provides convenient approximate ordering, not a guarantee of perfect global chronology.
When to Use UUID v4
UUID v4 is a strong choice when:
- maximum library and platform compatibility is required;
- creation time should not be visible in the identifier;
- the application already uses UUID v4 consistently;
- database insertion order is not a major concern;
- the values are exposed as public resource identifiers;
- the selected runtime does not yet support UUID v7;
- simple random generation is preferred.
UUID v4 remains a dependable general-purpose identifier and there is no need to replace it in systems where it already works well.
When to Use UUID v7
UUID v7 is worth considering when:
- UUIDs are used as indexed database primary keys;
- records should sort approximately by creation time;
- the application processes a high volume of inserts;
- the system stores events, logs, transactions, or audit records;
- services must generate identifiers independently;
- the development environment provides reliable UUID v7 support;
- exposing an approximate timestamp is acceptable.
It is especially suitable for new applications that need both distributed generation and database-friendly ordering.
Can an Application Use Both Versions?
Yes. A system may use different UUID versions for different purposes.
For example:
- UUID v7 for internal database keys;
- UUID v4 for public API identifiers;
- UUID v7 for event and audit records;
- UUID v4 for legacy integrations;
- UUID v4 for identifiers where time exposure is undesirable.
Mixing versions inside one column is possible, but it can make behavior harder to understand. Consistency within a table, service, or business domain is usually preferable.
Migration from UUID v4 to UUID v7
An application that already uses UUID v4 does not automatically need to migrate.
Changing primary keys may affect:
- foreign-key relationships;
- API URLs;
- cached objects;
- analytics systems;
- audit logs;
- external integrations;
- data warehouses;
- message payloads.
A safer approach is often to keep existing identifiers and introduce UUID v7 for new entities or services.
Migration should be based on a measurable requirement, such as index performance or the need for sortable identifiers, rather than simply adopting a newer format.
Implementation Checklist
Before selecting a UUID version, development teams should answer the following questions:
- Will the UUID be used as a database primary key?
- Does chronological sorting provide a real benefit?
- Is timestamp exposure acceptable?
- Does the runtime provide a maintained UUID v7 library?
- Will identifiers be public or internal?
- Which database column type will store the value?
- How will incoming UUIDs be validated?
- Does the application generate IDs at a high rate?
- Are existing systems dependent on UUID v4?
- Has the approach been tested under a realistic workload?
Final Recommendation
UUID v4 remains the best default when developers need maximum compatibility, random identifiers, and no embedded timestamp.
UUID v7 is often the better choice for new database-oriented systems, event platforms, logs, and high-volume applications that benefit from sortable identifiers and improved index locality.
The practical decision can be summarized as follows:
- Choose UUID v4ย for broad support, random ordering, and reduced timestamp exposure.
- Choose UUID v7ย for time-oriented records, database keys, and approximately chronological sorting.
Whichever version is selected, use a trusted UUID library, validate incoming values, store them efficiently, and enforce database uniqueness. UUIDs solve identifier generation, but they do not replace timestamps, authorization controls, or careful application design.

