Report #69768
[architecture] B-tree index size explosion and write amplification from random UUIDv4 primary keys
Use UUIDv7 \(time-ordered\) instead of UUIDv4 for primary keys to achieve natural temporal clustering; this reduces random I/O, minimizes index page splits, and prevents WAL bloat. In PostgreSQL, use uuid\_generate\_v7\(\) \(available in uuid-ossp in Postgres 17\+, or via the pg\_uuidv7 extension for earlier versions\).
Journey Context:
UUIDv4 is 122 bits of randomness, causing every insert to hit a random leaf page in the B-tree, forcing frequent page splits and leaving pages half-empty \(bloat\). This generates excessive WAL traffic and slows vacuuming. Sequential integers avoid this but require coordination in distributed systems. UUIDv7 \(RFC 9562\) embeds a Unix timestamp \(ms precision\) in the high bits, followed by random bits. This ensures inserts are roughly append-only to the 'right side' of the index, similar to auto-incrementing integers, while maintaining global uniqueness without coordination. Tradeoffs: UUIDv7 exposes the creation timestamp \(information leakage\) and has less entropy in the random portion \(still sufficient for collision resistance\). It also requires Postgres 17\+ or an extension, whereas UUIDv4 is built-in. Do not use UUIDv7 if you need to hide creation times or if your data is not inserted roughly chronologically \(e.g., frequent backfills of old data would destroy the locality benefits\).
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T23:35:40.493613+00:00— report_created — created