DTTooleras

UUID Guide: Versions, Use Cases, and Best Practices for Developers

Everything developers need to know about UUIDs — the differences between v1, v4, v5, and v7, when to use each version, database performance implications, and implementation in multiple languages.

DevToolsHub Team16 min read775 words

What is a UUID?

A UUID (Universally Unique Identifier) is a 128-bit identifier that is designed to be unique across space and time without requiring a central authority. UUIDs are formatted as 32 hexadecimal digits displayed in five groups separated by hyphens:

550e8400-e29b-41d4-a716-446655440000

The format is: xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

Where M indicates the UUID version and N indicates the variant.

UUID Versions

UUID v1 — Time-based

Generated from the current timestamp and the MAC address of the computer. This means:

  • Pros: Naturally sortable by creation time, guaranteed unique per machine
  • Cons: Exposes the MAC address (privacy concern), requires clock synchronization
  • Use when: You need time-ordering and don't care about privacy

UUID v3 — Name-based (MD5)

Generated by hashing a namespace UUID and a name using MD5:

// Same input always produces the same UUID
uuidv3("hello", uuidv3.URL);
// Always returns the same UUID for "hello" in the URL namespace
  • Pros: Deterministic — same input always gives same output
  • Cons: MD5 is cryptographically broken (though fine for UUID generation)
  • Use when: You need reproducible IDs from known inputs

UUID v4 — Random

Generated from random (or pseudo-random) numbers. This is the most commonly used version:

f47ac10b-58cc-4372-a567-0e02b2c3d479
  • Pros: Simple, no external dependencies, very low collision probability
  • Cons: Not sortable, poor database index performance (random distribution)
  • Use when: You need a simple unique identifier and don't need ordering

The probability of a collision with UUID v4 is astronomically low. You would need to generate about 2.71 quintillion UUIDs to have a 50% chance of a single collision.

UUID v5 — Name-based (SHA-1)

Same concept as v3 but uses SHA-1 instead of MD5:

  • Pros: Deterministic, uses stronger hash than v3
  • Cons: SHA-1 is also considered weak (but fine for UUID generation)
  • Use when: Same as v3, but prefer v5 for new projects

UUID v7 — Time-ordered Random (New!)

The newest version, specified in RFC 9562 (2024). Combines a Unix timestamp with random data:

018f3e5c-8c1a-7000-8000-1234567890ab
 ^^^^^^^^ ^^^^
 timestamp  |
            version 7
  • Pros: Sortable by creation time, excellent database index performance, no privacy concerns
  • Cons: Newer standard, less library support (growing rapidly)
  • Use when: You need unique IDs in a database (this is the best choice for most new projects)

UUID v4 vs v7: Database Performance

This is a critical consideration. UUID v4's randomness causes index fragmentation in B-tree indexes:

UUID v4 inserts (random order):
f47ac10b... → page 847
a1b2c3d4... → page 123
e5f6a7b8... → page 756
13579bdf... → page 45

UUID v7 inserts (time-ordered):
018f3e5c... → page 999 (latest page)
018f3e5d... → page 999 (same page!)
018f3e5e... → page 999 (same page!)
018f3e5f... → page 1000 (next page)

UUID v7 inserts are sequential, which means:

  • New rows go to the end of the index (no page splits)
  • Better cache utilization
  • 2-10x faster insert performance in benchmarks
  • Smaller index size over time

Recommendation: Use UUID v7 for database primary keys in new projects.

Generating UUIDs

JavaScript

// UUID v4 (built-in)
crypto.randomUUID();
// "f47ac10b-58cc-4372-a567-0e02b2c3d479"

// UUID v7 (manual implementation)
function uuidv7() {
  const timestamp = Date.now();
  const timestampHex = timestamp.toString(16).padStart(12, "0");
  const randomBytes = new Uint8Array(10);
  crypto.getRandomValues(randomBytes);
  const randomHex = Array.from(randomBytes)
    .map(b => b.toString(16).padStart(2, "0"))
    .join("");
  return [
    timestampHex.slice(0, 8),
    timestampHex.slice(8) + randomHex.slice(0, 1),
    "7" + randomHex.slice(1, 4),
    ((parseInt(randomHex.slice(4, 6), 16) & 0x3f) | 0x80)
      .toString(16) + randomHex.slice(6, 8),
    randomHex.slice(8, 20),
  ].join("-");
}

Python

import uuid

# UUID v4
print(uuid.uuid4())

# UUID v1
print(uuid.uuid1())

# UUID v5
print(uuid.uuid5(uuid.NAMESPACE_URL, "https://example.com"))

PostgreSQL

-- UUID v4 (built-in)
SELECT gen_random_uuid();

-- UUID v7 (PostgreSQL 17+)
SELECT uuidv7();

-- Use as primary key
CREATE TABLE users (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  name TEXT NOT NULL
);

Command Line

# Linux/macOS
uuidgen

# Using Python
python -c "import uuid; print(uuid.uuid4())"

Best Practices

  1. Use UUID v7 for database primary keys — Better performance than v4, no privacy issues like v1

  2. Don't use UUIDs when you don't need them — Auto-incrementing integers are simpler and more efficient for internal-only IDs

  3. Store as native UUID type — Most databases have a UUID type that stores 16 bytes. Don't store as VARCHAR(36) — that wastes space

  4. Consider ULID as an alternative — ULIDs are similar to UUID v7 but use Crockford's Base32 encoding, making them shorter and URL-safe

  5. Never assume UUIDs are secret — UUIDs are identifiers, not security tokens. Don't use them as authentication tokens or API keys

Generate UUIDs instantly with our UUID Generator tool.

uuiduuid v4uuid v7guiduuid generatoruuid databaseuuid best practices

Related articles

All articles

Practice with free tools

200+ free developer tools that run in your browser.

Browse all tools →