DailyTools
All articles
Developer ToolsMarch 11, 20268 min read

UUIDs Explained: Unique Identifiers for Distributed Systems and Databases

UUIDs power modern distributed systems, from database primary keys to API resources. Learn how UUID versions work, when to use each, and the trade-offs between UUIDs and auto-increment IDs.

Every record in a database, every resource exposed by an API, and every message in a distributed queue needs a unique identifier. For decades, auto-incrementing integers served this purpose perfectly. But as systems grew into microservice architectures, multi-region deployments, and offline-first applications, the limitations of sequential IDs became critical: they leak information (your competitor can estimate your user count), they require a central coordinator (the database sequence), and they collide when independent systems generate IDs simultaneously.

UUIDs (Universally Unique Identifiers) solve these problems by generating 128-bit identifiers so astronomically unlikely to collide that coordination between systems is unnecessary. Understanding the different UUID versions, their strengths, and their database performance implications is essential for any developer designing distributed systems.

UUID Format and Structure

A UUID is a 128-bit value displayed as 32 hexadecimal characters separated by hyphens in five groups: 8-4-4-4-12. For example: 550e8400-e29b-41d4-a716-446655440000. The 13th character (the first digit of the third group) indicates the UUID version. The 17th character indicates the variant (almost always 8, 9, a, or b for RFC 4122 UUIDs).

text
UUID format: xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
                                ^         ^
                                |         |
                            Version    Variant

Version 4 example: 550e8400-e29b-41d4-a716-446655440000
                                 ^
                             Version = 4 (random)

UUID Versions: Which to Use

  • UUID v1 (timestamp + MAC address): Encodes the generation time and the machine's network card MAC address. Guarantees uniqueness but leaks the creation time and the generating machine's identity. Rarely used in modern systems due to privacy concerns.
  • UUID v4 (random): Generated entirely from random or pseudo-random numbers. The most widely used version — simple to implement, no information leakage, no coordination required. The collision probability for 2^122 possible values is vanishingly small: you would need to generate 1 billion UUIDs per second for 85 years to have a 50% chance of a single collision.
  • UUID v7 (timestamp-ordered, 2022): A newer standard that embeds a Unix timestamp in the first 48 bits, making UUIDs sortable by creation time while remaining unique. This solves the database index performance problem of random v4 UUIDs. Supported by modern libraries and gaining rapid adoption.

UUIDs vs Auto-Increment IDs

The choice between UUIDs and auto-increment integers involves real trade-offs that affect performance, security, and architecture:

  • Information leakage: Sequential IDs reveal your record count, growth rate, and creation order. UUID v4 reveals nothing. This matters for user-facing IDs in URLs and APIs.
  • ID generation without coordination: Auto-increment requires a centralized sequence (the database). UUIDs can be generated by any client, server, or service independently — critical for offline-first apps and microservices.
  • Database index performance: Random UUID v4 values cause B-tree index fragmentation because inserts scatter across the index rather than appending at the end. This increases write amplification and slows queries on large tables. UUID v7 solves this with time-ordered prefixes.
  • Storage size: An integer ID uses 4-8 bytes. A UUID uses 16 bytes (as binary) or 36 bytes (as a string). On tables with millions of rows and multiple indexes, this difference compounds.
  • Human readability: Order #12847 is easy to communicate over the phone. UUID 550e8400-e29b-41d4-a716-446655440000 is not.

Generating UUIDs in Code

javascript
// Browser — crypto.randomUUID() (CSPRNG, UUID v4)
const id = crypto.randomUUID();
// → "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed"

// Node.js — built-in since v14.17
const { randomUUID } = require('crypto');
const id = randomUUID();

// Python
import uuid
id = uuid.uuid4()  # Random UUID v4

// PostgreSQL — built-in function
-- UUID v4 (requires pgcrypto or gen_random_uuid in PG 13+)
SELECT gen_random_uuid();

// Store UUIDs as binary (16 bytes) not strings (36 bytes)
-- PostgreSQL: use the native UUID type
-- MySQL: use BINARY(16) with UUID_TO_BIN() / BIN_TO_UUID()

Database Best Practices

  • Store UUIDs as binary (16 bytes), not as VARCHAR(36) strings — saves 55% storage and dramatically improves index performance
  • Prefer UUID v7 for primary keys — time-ordered prefixes maintain B-tree insert performance comparable to auto-increment
  • If using UUID v4, consider a separate auto-increment column for the clustered index and use the UUID as a secondary unique index for external lookups
  • PostgreSQL's native UUID type stores 16 bytes and supports indexing efficiently — always use it over text
  • In MySQL, use UUID_TO_BIN(uuid, 1) with the swap flag to reorder bytes for better index locality

Alternatives to UUIDs

Several alternative ID formats address specific UUID shortcomings:

  • ULID (Universally Unique Lexicographically Sortable Identifier): 128-bit, time-ordered, Crockford Base32 encoded (26 characters). Monotonically sortable within the same millisecond. A popular UUID v7 alternative.
  • Snowflake IDs (Twitter): 64-bit integers encoding timestamp + machine ID + sequence number. Compact, sortable, and unique across a coordinated cluster. Used by Twitter, Discord, and Instagram.
  • NanoID: Customizable-length random string using a URL-safe alphabet. Shorter than UUIDs (21 characters by default) with comparable collision resistance. Popular for user-facing IDs.
  • CUID2: Collision-resistant, horizontally scalable IDs designed specifically for web applications. Monotonically sorted, URL-safe, and shorter than UUIDs.

Try the free tool referenced in this article

UUID Generator