PostgreSQL UUID Performance: Random (v4) vs Time-Ordered (v7)โโโA Deep Dive ๐ฏ
How ordered UUIDs dramatically improve insert speed, index locality, and overall throughput.
PostgreSQL UUID Performance: Random (v4) vs Time-Ordered (v7) โ A Deep Dive ๐ฏ
How ordered UUIDs dramatically improve insert speed, index locality, and overall throughput.

Introduction
Choosing the right primary key strategy is one of the subtle yet impactful decisions in database design. For a long time, random UUIDs (commonly version 4) have been used to guarantee global uniqueness across distributed systems โ but at a cost. Recently, a growing body of evidence (and community practice) shows that the newer time-based UUIDs (version 7) significantly outperform classic v4 in modern databases like PostgreSQL.
In this article, we break down:
- What really changes between UUIDv4 and UUIDv7,
- What benchmarks show (especially in PostgreSQL),
- The trade-offs and caveats, and
- Practical recommendations for 2025 database design.
What Are UUIDv4 and UUIDv7?
๐น UUID Basics
A UUID (Universally Unique Identifier) is a 128-bit value, designed to provide a unique identifier for entities across distributed systems.
- Historically, many systems prefer UUIDs over auto-increment integers when they need globally unique IDs without coordination.
- The standard representation โ 32 hexadecimal digits separated by hyphens โ hides the internal bit structure but preserves uniqueness.
UUIDv4: Random, Globally Unique, Unordered
- In version 4, most bits are filled randomly (except the version and variant bits) โ giving high entropy and strong uniqueness across systems.
- The downside: because new IDs are randomly distributed, when used as primary keys (often backed by a B-tree index), inserts scatter across the index. This causes page splits, fragmented pages, poor locality, and thus degrades insert performance and increases index maintenance overhead.
UUIDv7: Time-Based, Ordered, Index-Friendly
- Introduced in the updated standard (post-RFC 9562 era), version 7 UUIDs embed a timestamp (often milliseconds since epoch) in their highest-order bits. The rest of the bits provide randomness for uniqueness.
- The result: UUIDv7s are still globally unique, but roughly monotonically increasing over time โ which means when you insert entries chronologically, the database index sees nearly sequential inserts. That dramatically reduces page splits/fragmentation, improves locality (cache friendliness), and speeds up both inserts and ordered/temporal queries.
- As of 2025, support for native UUIDv7 generation has been added in PostgreSQL 18.
The Benchmarks โ What Does Reality Show?
The recent benchmark published under the title โPostgreSQL UUID Performance: Benchmarking Random (v4) and Time-based (v7) UUIDsโ gives numbers that support the theory: v7 improves both latency and throughput in practice.
โก Core Benchmark Results (PostgreSQL 18)
1. Insert Latency
- UUIDv4 (random): around 86.8 microseconds
- UUIDv7 (time-based): around 58.1 microseconds
โ UUIDv7 reduces insert latency by roughly 33%.
2. Insert Throughput (single-thread tests)
- UUIDv4: ~ 29,238 operations/second
- UUIDv7: ~ 34,127 operations/second
โ UUIDv7 delivers ~16% higher throughput.
3. Index Behavior (B-Tree, default settings)
UUIDv4:
- Causes scattered inserts
- Frequent page splits
- Higher index maintenance overhead
- More random I/O
UUIDv7:
- Inserts arrive in natural time-order
- Minimizes page splits
- Better locality and cache behavior
- Reduced write amplification
โ UUIDv7 behaves much closer to sequential integers than to random UUIDs.
4. Overall Performance Summary
- UUIDv7 keeps the benefits of global uniqueness
- Provides significantly better index locality
- Reduces fragmentation
- Improves both write speed and read efficiency
- Works extremely well for high-write or time-series workloads
โ In PostgreSQL 18, UUIDv7 is objectively superior to UUIDv4 for most real-world use cases.
Why Time-Order Matters: Index Locality & B-Tree Behavior
To understand why v7 performs better, you must understand how B-trees behave under insert patterns:
- With random keys (UUIDv4), new inserts land โeverywhereโ in the B-tree. That causes frequent page splits, scattered pages, poor locality, and higher I/O for writes โ especially under high insert volume.
- With time-ordered keys (UUIDv7), new inserts tend to go to the โendโ (or near-end) of the index. That leads to sequential insertion behavior โ the B-tree can append instead of splitting โ better page-fill, fewer splits, more cache-friendly I/O, and lower fragment overhead.
- This effect improves not only insert speed, but also range queries, ordered scans, clustering, and temporal queries (e.g. โall records created after time Tโ), because the physical order in the index reflects insertion time order naturally.
Trade-offs & Caveats โ Use With Awareness
While UUIDv7 is a very compelling upgrade over UUIDv4, itโs not a silver bullet. There are trade-offs and things to watch out for:
โ ๏ธ Time Leakage / PrivacyBecause v7 embeds a timestamp (often with millisecond resolution), anyone seeing the UUID can infer roughly when that record was created. That may be a concern if IDs are public (e.g. exposed in URLs) and timestamp privacy is needed.
๐งฐ Implementation & Compatibility
- UUIDv7 is relatively new. While PostgreSQL 18 (as of 2025) adds native support, older versions (or other databases) may not support v7 natively.
- In such cases you must rely on external libraries at application-level to generate UUIDv7 โ which is fine, but introduces dependency/version management overhead.
๐ฆ Still Larger than Integer IDs
UUIDs (v4 or v7) still occupy 16 bytes (128 bits). If your workload is such that ID generation is local and you donโt need global uniqueness, a compact integer (e.g. BIGINT, 8 bytes) might still be more efficient in space & index size.
๐ Not Perfect for All Use Cases
- If you need cryptographically secure, unpredictable IDs (e.g. for security-sensitive tokens), a fully random scheme like UUIDv4 (or other cryptographic IDs) may still be preferable to timestamp-based ones.
- If your writes are extremely distributed and clock skew across machines is possible โ you must ensure clock sync, or risk out-of-order IDs or duplicates (rare but theoretically possible).
How to Adopt UUIDv7 in PostgreSQL (2025)
If youโre using PostgreSQL (15 / 16 / 17 / 18), hereโs how you can adopt UUIDv7 for new or existing schemas:
- Use PostgreSQL 18 (or newer) โ it natively supports
uuidv7()generation. - For older versions: generate UUIDv7 at application layer using a library (many languages now support v7). Store it in a
UUIDcolumn. - Define primary key using
UUIDtype (just like youโd do with UUIDv4) and let B-tree build the index. - Benchmark under realistic load (inserts + reads + concurrency) โ to verify gains in your environment.
- If you have existing tables using UUIDv4, consider a migration path: add a new
uuid_v7column, backfill, switch keys โ depending on downtime tolerance.
Where UUIDv7 Makes Most Sense
Here are some common use-cases in 2025 where choosing UUIDv7 is especially beneficial:
- Distributed microservices generating IDs independently, needing global uniqueness + good DB performance.
- High-write workloads: logs, audit trails, event tracking, analytics pipelines โ where insert performance, write throughput, and temporal ordering matter.
- Systems that require roughly time-ordered data for queries, maintenance or ordering (e.g. โshow me recent usersโ, time-series data, incremental processing).
- Apps using PostgreSQL 18+ or other modern DBs supporting time-ordered UUIDs โ wanting a drop-in identifier scheme without moving to auto-increment integers.
Summary & Recommendation
- UUIDv4 โ fully random UUIDs โ were great for global uniqueness, but suffer serious performance hits in B-tree indexes due to poor locality and fragmentation.
- UUIDv7 โ the time-based, ordered successor โ preserves global uniqueness while significantly improving insert throughput, index locality, and query performance, especially for temporal workloads.
- Benchmarks (on PostgreSQL 18) show ~ 33% lower latency and ~ 16% higher throughput for inserts using UUIDv7 vs UUIDv4.
- Caveats remain (timestamp leakage, size vs integer, compatibility), but for many modern applications, UUIDv7 is the strongest default choice when you need UUID-style identifiers.
Recommendation (2025): If you are designing a new system or thinking of scaling an existing one โ prefer UUIDv7 (or similar time-ordered IDs) over UUIDv4. For legacy or small-scale use cases where simplicity and space efficiency matter, integer keys still make sense.
๐ Want to Explore more in UUID performance?
๋ฉํ๋ฐ์ดํฐ
- post_id
- 067b2de044ef
- slug
- postgresql-uuid-performance-random-v4-vs-time-ordered-v7-a-deep-dive-067b2de044ef
- url
- https://medium.com/@sonal.sadafal/postgresql-uuid-performance-random-v4-vs-time-ordered-v7-a-deep-dive-067b2de044ef
- canonical_url
- https://medium.com/@sonal.sadafal/postgresql-uuid-performance-random-v4-vs-time-ordered-v7-a-deep-dive-067b2de044ef
- author_url
- https://medium.com/@sonal.sadafal
- status
- ok
- fetched_at
- 2026-07-15 08:17:25