If you build software that syncs data across devices, exposes a public API, or runs on multiple servers, you’ve probably hit the auto-increment ID problem: two systems generate the same ID and suddenly records overwrite each other. UUIDs (Universally Unique Identifiers) solve this by letting any machine generate a globally unique ID with zero coordination. This guide covers the developer-focused details: using UUIDs as primary keys, performance tradeoffs, and best practices. Generate test IDs quickly with the UUID Generator while you read.
Why Use UUIDs as Primary Keys
Three scenarios make UUID primary keys the right call:
- Offline-first apps: A mobile app creates a record with no connection — the ID must not collide with IDs created later on the server or another device
- Distributed/microservice systems: Multiple services write to the same logical dataset; no single database can hand out sequential IDs fast enough
- Public-facing IDs: UUIDs hide record counts and are not enumerable — attackers can’t walk through
/users/1,/users/2,/users/3
Performance: The Real Tradeoff
The common objection to UUID primary keys is index performance. It’s valid — but only for v4 (random) UUIDs. Random values scatter inserts across the entire B-tree index, causing page splits and cache misses on large tables. The fix:
- Use UUID v7 — it embeds a timestamp prefix, so new rows insert sequentially just like auto-increment IDs. PostgreSQL 18+ and many libraries now support v7 natively.
- Use a UUID as a secondary key — keep an integer auto-increment for the clustered index and add a unique UUID column for external references.
- Store as binary (16 bytes) — never as a 36-char string. Binary storage halves index size and speeds lookups.
UUID v4 vs v7: Which to Pick in Code
| Needs | Recommendation |
|---|---|
| Maximum simplicity, no ordering needs | v4 (random) |
| Sortable by creation time, large tables | v7 (timestamp + random) |
| Same ID for same input (dedup, idempotency) | v5 (SHA-1 namespace) |
| Time traceability, legacy systems | v1 (timestamp + MAC) |
Best Practices
- Generate on the client when offline matters — the whole point is that any node can mint an ID
- Normalize format before storing — always lowercase, with hyphens, to keep comparisons and indexes consistent
- Don’t put UUIDs in URLs unless you want them public — for internal IDs, keep them out of client-facing URLs
- Use them for idempotency keys — an API client sends the same UUID for retries so the server can deduplicate
- Bulk-test before migration — generate a few hundred with the UUID Generator to check format compatibility with your database column type
Quick Code Reference
Most languages make UUID generation a one-liner:
# Python
import uuid
print(uuid.uuid4()) # v4
print(uuid.uuid7()) # v7 (Python 3.14+)
// JavaScript
crypto.randomUUID() // v4, built into Node 19+ and browsers
Whether you’re designing a schema for a new service or fixing ID collisions in an existing one, starting with the right UUID version saves you a painful migration later. Generate and experiment with the free UUID Generator today.


Leave a Reply
You must be logged in to post a comment.