UUIDs Explained: v4 vs v7 and When to Use Them
A UUID is a 128-bit identifier designed to be unique without a central authority assigning it. You can generate one on your laptop, one on a server in Tokyo, and one on a phone in São Paulo — simultaneously — and the odds of a collision are so small they're practically fictional. But "UUID" covers several very different designs, and picking the wrong version for a database primary key can quietly destroy query performance. Here is everything you need to know to make the right call.
The Structure: What Those 32 Hex Characters Actually Mean
A UUID looks like this: 550e8400-e29b-41d4-a716-446655440000. It is 128 bits rendered as 32 hexadecimal digits in five groups separated by hyphens (8-4-4-4-12). Two of those bits are reserved for the variant field (indicating the RFC 4122 layout), and 4 bits encode the version. The remaining 122 bits carry the actual identifier payload.
The version nibble sits at the start of the third group. That single hex digit — 4 for v4, 7 for v7 — determines almost everything about how the UUID behaves at scale.
Collision Math: Why Randomness Is Safe Enough
UUID v4 fills all 122 free bits with random data (from a cryptographically secure RNG). The birthday-problem formula gives the probability of at least one collision among n generated UUIDs as approximately:
P ≈ 1 − e^(−n² / 2 × 2¹²²)
Plugging in numbers: to reach even a 1-in-a-billion chance of a single collision, you would need to generate roughly 1.1 × 10¹⁸ UUIDs — over a quintillion. At a rate of one billion UUIDs per second, that takes about 36 years of continuous generation. For any realistic application, collisions simply do not happen.
The practical danger is not the math — it is a broken RNG. Systems that seed a PRNG with a low-entropy value (boot time, PID) can produce predictable UUIDs. Always use your platform's OS-level secure random source: crypto.randomUUID() in browsers and Node.js, uuid.uuid4() backed by os.urandom() in Python, or UUID.randomUUID() in Java.
UUID v4 vs v7: The Core Difference
UUID v7, standardized in RFC 9562 (2024), replaces the leading random bits with a 48-bit Unix millisecond timestamp. The remaining 74 bits are random. This one change has enormous practical consequences for databases.
| Property | UUID v4 | UUID v7 |
|---|---|---|
| Introduced | RFC 4122 (2005) | RFC 9562 (2024) |
| Leading bits | Random | 48-bit ms timestamp |
| Random bits | 122 | 74 |
| Sortable by creation time | No | Yes (lexicographic) |
| Collision resistance | Extremely high | Extremely high* |
| DB index fragmentation | Severe | Minimal |
| Reveals creation time | No | Yes (ms precision) |
* Two v7 UUIDs generated within the same millisecond on the same node still have 74 random bits — roughly 1.9 × 10²² possible values per millisecond per node. Collision risk is negligible.
Why v4 Destroys B-Tree Index Performance
Every major relational database — PostgreSQL, MySQL, SQL Server, SQLite — stores primary key indexes as a B-tree. B-trees perform best when new rows land at the end of the index (monotonically increasing keys). With UUID v4, each new insert hashes into a random position in the tree, forcing the database to:
- Read an existing index page into memory
- Split the page roughly half the time (page splits are expensive writes)
- Leave pages 50–70% full on average rather than the ideal 90%+
At tens of millions of rows, this causes write amplification that can be 3–5× worse than a sequential key. Benchmarks on PostgreSQL with 50 million rows typically show UUID v4 inserts running 2–4× slower than BIGSERIAL and index sizes 40–60% larger due to fragmentation.
UUID v7 fixes this entirely. Because the timestamp prefix monotonically increases, new rows always append to the rightmost leaf of the B-tree, exactly like an auto-increment integer. You get the operational benefits of a distributed ID (no central sequence, embeddable in URLs, safe to generate client-side) with none of the index-fragmentation penalty.
GUIDs: Same Thing, Different Name
Microsoft coined the term GUID (Globally Unique Identifier) for their implementation of UUIDs in COM, ActiveX, and Windows APIs. A GUID is byte-for-byte identical to a UUID under RFC 4122. The only practical differences are cosmetic: GUIDs are often displayed in uppercase and wrapped in curly braces — {550E8400-E29B-41D4-A716-446655440000} — whereas UUIDs conventionally use lowercase with no braces. When a Windows API or .NET method returns a Guid, you can store it in a UUID column in any SQL database without any conversion.
SQL Server historically defaulted to its own sequential GUID variant called NEWSEQUENTIALID(), which prepends a timestamp — essentially the same idea as UUID v7, predating the RFC by almost two decades.
When NOT to Use UUIDs
UUIDs are not always the right tool. Avoid them when:
- You need human-readable IDs. A UUID in a support ticket number or invoice ID is hostile to users. Use a short alphanumeric code (
INV-2024-00483) instead. - Storage is constrained. A UUID stored as a
VARCHAR(36)text string costs 36 bytes; as a nativeUUIDorBINARY(16)column it costs 16 bytes. In a table with hundreds of millions of rows and several UUID foreign keys, the difference can be gigabytes. Always use the native binary type. - You need true secrecy. UUID v7 leaks creation timestamp to the millisecond. If exposing when a record was created is a privacy concern (user IDs, medical records), use v4 or an opaque token from a separate secrets system.
- Single-node, low-volume systems. If your app runs on one server and inserts fewer than a million rows per table over its lifetime, a plain auto-increment integer is simpler, faster, and just as collision-free. Don't reach for UUIDs out of habit.
- URL shorteners and QR codes. A 36-character UUID in a URL is impractical. Use a base-62 encoded random token of 8–12 characters instead.
Quick Decision Guide: Which UUID Version to Use
- New database primary key (Postgres, MySQL, SQLite): Use v7. Sortable, index-friendly, timestamp included.
- Correlation ID in logs or distributed tracing: Use v4. Timestamp not needed; pure randomness avoids any information leakage.
- Legacy system that already uses v4: No need to migrate. The collision risk is not your problem. Migrate if you hit real index-fragmentation pain.
- Client-side generated ID (browser, mobile) that will be stored server-side: Use v7 — the timestamp makes it auditable and the DB will thank you.
- Interoperability with Windows/.NET: A GUID is a UUID; store as
BINARY(16)or the native UUID type, strip the curly braces.
The free UUID generator on this site produces both v4 and v7 in standard, uppercase, and URN formats — copy the one you need without writing a line of code.
अक्सर पूछे जाने वाले सवाल
Can two UUID v4 values ever be the same?+
Theoretically yes, practically no. You would need to generate roughly 1.1 × 10¹⁸ UUIDs to reach a one-in-a-billion chance of a collision. The risk is orders of magnitude smaller than hardware failure or memory corruption — treat it as zero.
Is UUID v7 backward compatible with v4?+
Yes. Both are 128-bit values in the same RFC 4122 / RFC 9562 layout. Any system that accepts a UUID column or field will accept v7 without changes. The version nibble (7 instead of 4) is the only structural difference.
Should I store UUIDs as strings or binary in my database?+
Always use the native binary type when available — UUID in PostgreSQL, BINARY(16) in MySQL, or uniqueidentifier in SQL Server. VARCHAR(36) wastes 2.25× the storage and is slower to index. Only use string storage if your ORM or driver forces it.
Does UUID v7 expose when my records were created?+
Yes — the first 48 bits encode the Unix timestamp in milliseconds, so anyone with the UUID can extract the creation time to within about 1ms. This is a feature for databases (sortability) but a concern for privacy-sensitive IDs like user accounts. Use v4 if that matters.
What is the difference between a UUID and a GUID?+
Nothing meaningful. GUID is Microsoft's name for the same 128-bit identifier standard. The bits are identical; the only differences are display conventions (GUIDs are often uppercase with curly braces). They are fully interchangeable in storage.