Skip to main content
Blog / Development

Understanding UUID Generation - Complete Guide to Unique Identifiers

Learn everything about UUIDs (Universally Unique Identifiers), how they work, different versions, and best practices for generating unique IDs in your applications.

DevToolsCenter Team
8 min read

What is a UUID?

A UUID (Universally Unique Identifier) is a 128-bit identifier designed to be unique across time and space without requiring centralized coordination. UUIDs are standardized in RFC 4122 and are represented as 32 hexadecimal digits, displayed in five groups separated by hyphens.

UUID Format

xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Example: 550e8400-e29b-41d4-a716-446655440000

Why Use UUIDs?

UUIDs provide several advantages over sequential IDs:

  • Uniqueness: Extremely low probability of collisions across distributed systems
  • Distributed Generation: Can be generated without coordination
  • Privacy: Don't reveal information about data volume or sequence
  • Security: Harder to guess or enumerate than sequential IDs
  • Database Merging: Safe to merge records from different databases

UUID Versions

Version 1 (Time-based)

Generated using MAC address and timestamp:

  • Pros: Guaranteed uniqueness (MAC address + timestamp)
  • Cons: Reveals MAC address and creation time, potential privacy concern
  • Use Case: When you need sortable, time-based ordering
550e8400-e29b-11d4-a716-446655440000
        ^
    Version: 1

Version 2 (DCE Security)

Similar to v1, but includes POSIX UID/GID:

  • Rarely Used: Limited to specific DCE applications

Version 3 (Name-based MD5)

Generated from a namespace and name using MD5 hashing:

  • Deterministic: Same input always produces same UUID
  • Use Case: Creating UUIDs from names that need to be consistent
uuidv3('example.com', uuid.NAMESPACE_DNS)
// Always returns the same UUID for 'example.com'

Version 4 (Random)

Generated using random or pseudo-random numbers:

  • Most Common: Widely used in modern applications
  • Pros: No privacy concerns, truly random
  • Cons: No inherent ordering or meaning
  • Use Case: General-purpose unique identifiers
550e8400-e29b-41d4-a716-446655440000
        ^
    Version: 4 (random)

Version 5 (Name-based SHA-1)

Similar to v3, but uses SHA-1 hashing:

  • Better Security: SHA-1 is more secure than MD5
  • Use Case: Creating deterministic UUIDs from names
// JavaScript (uuid library)
import { v5 as uuidv5 } from 'uuid';
const ns = uuidv5.DNS; // or a custom namespace UUID
const id = uuidv5('example.com', ns);
# Python
import uuid
ns = uuid.NAMESPACE_DNS
id = uuid.uuid5(ns, 'example.com')

UUID Structure

A UUID consists of five hexadecimal groups:

550e8400-e29b-41d4-a716-446655440000
└───┬───┘└─┬─┘└─┬─┘└─┬─┘└─────┬─────┘
    │     │    │    │        └─ Node (12 hex digits)
    │     │    │    └─ Variant (2 hex digits)
    │     │    └─ Version (1 hex digit)
    │     └─ Clock Sequence (4 hex digits)
    └─ Time Low (8 hex digits)

When to Use UUIDs

✅ Good Use Cases

  • Distributed Systems: Multiple servers generating IDs independently
  • Database Merging: Combining data from different sources
  • Privacy-Sensitive Applications: IDs that shouldn't reveal information
  • Offline Generation: Creating IDs before database insertion
  • Microservices: Independent service ID generation

❌ When Not to Use UUIDs

  • Sequential IDs Needed: When you need chronological ordering
  • Performance Critical: Sequential integers are faster for indexing
  • Storage Constraints: UUIDs require 16 bytes vs 4-8 bytes for integers
  • Human Readability: UUIDs are not human-friendly

UUID Best Practices

Database Considerations

Primary Keys:

-- Good: UUID as primary key
CREATE TABLE users (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  username VARCHAR(50)
);

-- Index performance considerations
CREATE INDEX idx_users_created ON users(created_at);

Indexing:

  • UUIDs can impact database performance due to randomness
  • Consider using UUID v1 if you need sortable IDs
  • Use BRIN indexes (PostgreSQL) for UUID columns when possible

Generation Strategies

Client-Side Generation:

// Generate UUID v4 before database insertion
const userId = crypto.randomUUID(); // Browser API
const record = { id: userId, name: "John" };
await db.insert(record);

Server-Side Generation:

// PostgreSQL
INSERT INTO users (id, name) 
VALUES (gen_random_uuid(), 'John');

// MySQL 8.0+
INSERT INTO users (id, name) 
VALUES (UUID(), 'John');

Performance Tips

  1. Database Indexing: Ensure proper indexes on UUID columns
  2. Sorting: Use created_at timestamps instead of UUIDs for sorting
  3. Pagination: Use timestamp-based pagination with UUIDs
  4. Binary Storage: Store UUIDs as binary (16 bytes) instead of strings (36 chars)

Common Patterns

Generating UUIDs

JavaScript (Browser):

// Modern browsers
const uuid = crypto.randomUUID();
// → "550e8400-e29b-41d4-a716-446655440000"

Node.js:

const { randomUUID } = require('crypto');
const uuid = randomUUID();

Python:

import uuid
uuid_v4 = uuid.uuid4()

SQL:

-- PostgreSQL
SELECT gen_random_uuid();

-- MySQL 8.0+
SELECT UUID();

-- SQL Server
SELECT NEWID();

URL-Safe UUIDs

Prefer encoding the 16-byte UUID into Base64URL for compact, URL-safe IDs.

// Convert hyphenated UUID string -> Uint8Array (16 bytes)
function uuidToBytes(uuid) {
  const hex = uuid.replace(/-/g, '');
  const bytes = new Uint8Array(16);
  for (let i = 0; i < 16; i++) {
    bytes[i] = parseInt(hex.substr(i * 2, 2), 16);
  }
  return bytes;
}

// Uint8Array -> Base64URL string
function bytesToBase64Url(bytes) {
  let binary = '';
  for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
  const b64 = btoa(binary);
  return b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, '');
}

const uuid = "550e8400-e29b-41d4-a716-446655440000";
const b64url = bytesToBase64Url(uuidToBytes(uuid));
// Example → "VQ6EAOKbQdSnFkZmVURAQA"

Shortened UUIDs

For shorter URLs, encode UUID as Base64URL:

// 16-byte UUID → 22-character Base64URL string
const uuid = "550e8400-e29b-41d4-a716-446655440000";
const short = btoa(uuid.replace(/-/g, ''))
  .replace(/\+/g, '-')
  .replace(/\//g, '_')
  .replace(/=/g, '');
// → "VQ6EAOm50U2nFkRmVVQQAA"

UUID Collision Probability

The probability of a collision is extremely low:

  • Version 4 (Random): ~5.3 × 10⁻³⁷ chance of collision
  • 1 Billion UUIDs: ~2.7 × 10⁻¹⁸ collision probability
  • Practical Use: Effectively zero chance of collision for any practical application

Comparison with Other ID Strategies

Sequential Integers

Pros: Fast, small, sortable
Cons: Predictable, requires coordination

UUIDs

Pros: Unique, distributed, private
Cons: Larger, random, less efficient indexing

Snowflake IDs

Pros: Sortable, distributed, includes timestamp
Cons: More complex, larger than integers

Conclusion

UUIDs are an excellent choice for generating unique identifiers in distributed systems, modern web applications, and scenarios where privacy and distribution are important. While they come with some performance considerations, the benefits often outweigh the costs, especially in microservices architectures and cloud-native applications.

Understanding the different UUID versions and their use cases will help you choose the right approach for your specific requirements.

Try UUID Generator Now

Ready to put this into practice? Use our free UUID Generator tool. It works entirely in your browser with no signup required.

Launch UUID Generator
Free Forever No Signup Browser-Based

Frequently Asked Questions

Q Which UUID version should I use?

A

Use v4 for random IDs; use v1 if you need time-ordered IDs and accept metadata leakage risks.