Stop Using UUIDs in Your Database (Unless You Know What You’re Doing)

UUIDs might sound like a modern, scalable solution — but they often introduce performance bottlenecks, indexing headaches, and unnecessary…

Stop Using UUIDs in Your Database (Unless You Know What You’re Doing)
Photo by Caspar Camille Rubin on Unsplash

Not all IDs are created equal — and UUIDs may be doing more harm than good.

Stop Using UUIDs in Your Database (Unless You Know What You’re Doing)

UUIDs might sound like a modern, scalable solution — but they often introduce performance bottlenecks, indexing headaches, and unnecessary complexity.

There’s a trend in modern development circles that goes something like this:

“Hey, let’s use UUIDs for our database IDs — they’re globally unique, secure, and future-proof.”

Sounds smart, right?

Not always.

While UUIDs (Universally Unique Identifiers) have some solid use cases, developers are increasingly slapping them onto databases without understanding the trade-offs. And that can quietly cripple the performance, readability, and maintainability of your application.

Let’s break down why UUIDs might not be the silver bullet they’re hyped up to be — and when you actually should use them.


What Are UUIDs, Really?

UUIDs are 128-bit values used to uniquely identify data across systems. Here’s a sample:

9c858901-8a57-4791-81fe-4c455b099bc9

They come in different versions (v1, v4, etc.), but developers most commonly use UUIDv4, which is randomly generated. The appeal?

  • Globally unique (across machines and time)
  • Hard to guess, improving security
  • Great for distributed systems

But in the context of a relational database, these advantages can quickly backfire.

Problem #1: UUIDs Kill Index Performance

Relational databases like PostgreSQL or MySQL optimize for sequential keys. Auto-incrementing integers work beautifully for B-tree indexes because new rows are added in order — resulting in fast insertions and compact storage.

UUIDs? They’re essentially random.

This means every insert is like shoving a puzzle piece into a random part of the index. The result?

  • Frequent index page splits
  • Fragmentation of your B-tree
  • Slower inserts and range queries
  • Heavier I/O operations

And yes, performance will degrade as your dataset grows.

Problem #2: They’re Bigger Than You Think

Compare the sizes:

  • INT → 4 bytes
  • BIGINT → 8 bytes
  • UUID → 16 bytes

That doesn’t seem like much until you multiply it across millions of rows, foreign keys, and indexes.

Some consequences:

  • Your indexes are twice the size
  • Cache efficiency drops significantly
  • You burn through storage faster

If you’re working with analytics-heavy or write-intensive workloads, this inefficiency adds up — fast.

Problem #3: Poor Developer Experience

Let’s be honest — UUIDs are a pain to work with manually.

Want to debug a record? Compare:

SELECT * FROM orders WHERE id = 1245;

vs

SELECT * FROM orders WHERE id = '9c858901-8a57-4791-81fe-4c455b099bc9';

UUIDs:

  • Are harder to read
  • Cannot be sorted chronologically (UUIDv4, especially)
  • Make log parsing and troubleshooting less intuitive

And if you’re dealing with clients, support tickets, or audit trails, simple, numeric IDs are just easier to handle.

Problem #4: They Break Database Sharding Myths

Many developers adopt UUIDs under the false impression that they’re ideal for sharded or distributed databases.

The truth?

  • UUIDv4 is too random for ordered writes — it hurts distributed performance.
  • UUIDv1 embeds timestamps, but also includes MAC addresses, which raise privacy concerns.
  • Alternatives like ULIDs or KSUIDs are better for ordered uniqueness.

If you’re going distributed, choose intentionally ordered IDs designed for distributed systems — not just vanilla UUIDs.

Problem #5: Security Isn’t as Strong as You Think

Another common argument for UUIDs: they’re more secure than integers.

Yes — if you’re exposing IDs in URLs or APIs, UUIDs are harder to guess. But relying on UUIDs for security is like locking your door with a string of numbers:

  • UUIDs can still be enumerated in bulk exports or logs
  • UUIDv1 reveals MAC address and timestamp info
  • Security through obscurity is not real security

Instead, sanitize your endpoints and apply proper auth/permissions. Don’t trust your ID format to secure your system.

So, When Should You Use UUIDs?

To be fair, UUIDs aren’t evil. They shine in a few well-defined scenarios:

When You Truly Need Global Uniqueness

If multiple systems are generating IDs independently (e.g., syncing across services or microservices), UUIDs prevent collisions without coordination.

When Records Are Created Offline

Apps that need to generate IDs client-side (like mobile apps or IoT devices) can use UUIDs and sync later — useful for disconnected architectures.

When Privacy Is a Must

In some APIs or public-facing URLs, exposing sequential IDs could leak business info (like how many users you have). UUIDs are a lightweight way to mitigate that.

When Using NoSQL or Event-Sourced Systems

In distributed databases like Cassandra or DynamoDB, UUIDs can work — if you’re aware of the trade-offs.


Better Alternatives to UUIDs

If you’re tempted by UUIDs, first consider these options:

ULID (Universally Lexicographically Sortable Identifier)

  • Encodes timestamp in the ID
  • Still globally unique
  • Chronologically sortable
  • Easier to index and debug

Example: 01H9ZQ0BP3N6M42Q2ARW2SM2WD

KSUID (K-Sortable Unique Identifier)

  • From Segment.com
  • Sortable, time-encoded
  • 27 characters, URL-safe

Snowflake ID (used by Twitter, Instagram, etc.)

  • 64-bit integers with embedded timestamp, shard ID, and sequence
  • Short, sortable, and fast

Good Old Auto-Increment Integers

If you’re using a single relational database and don’t need to sync IDs across systems — just use integers. They’re:

  • Fast
  • Easy to index
  • Human-friendly
  • Efficient at scale

Final Thoughts: UUIDs Are a Tool — Not a Default

Too many developers reach for UUIDs by default, chasing scalability, security, or modernity — but end up creating more problems than they solve.

Instead of blindly adopting UUIDs:

  • Think critically about your architecture
  • Choose IDs based on your performance and usability needs
  • Understand the trade-offs before reaching for that 36-character monster

Use the right tool for the job — not just the trend.

Photo by Matthieu Beaumont on Unsplash