Back to Tools

UUID Generator

Generate UUIDs (Universally Unique Identifiers) in multiple versions. Perfect for unique identifiers, testing, and resource naming.

Random UUID (most common)
150

What is a UUID?

A UUID (Universally Unique Identifier) is a 128-bit identifier that is designed to be unique across time and space without requiring a central coordinating authority. UUIDs are also known as GUIDs (Globally Unique Identifiers) in Microsoft's terminology.

UUIDs are represented as 32 hexadecimal digits, displayed in five groups separated by hyphens:

xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Example UUID:

550e8400-e29b-41d4-a716-446655440000

Why UUIDs Matter

  • Distributed systems: Generate unique IDs without coordination
  • Database primary keys: Avoid collisions across multiple databases
  • API resource identifiers: Unique resource IDs in REST APIs
  • Session management: Unique session identifiers
  • File naming: Unique filenames without conflicts
  • Cloud resources: Unique identifiers for cloud resources

UUID Format

Structure

A UUID consists of 128 bits (16 bytes) represented as 32 hexadecimal digits:

xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

Where:

  • xxxxxxxx-xxxx: Time low (v1) or random (v4)
  • Mxxx: Version number (1-7) in the most significant 4 bits
  • Nxxx: Variant bits (identifies UUID layout)
  • xxxxxxxxxxxx: Node ID (v1) or random (v4)

Version Numbers

The version is encoded in the 13th character (4 bits):

VersionCharacterDescription
v11Time-based UUID
v22DCE Security UUID (rarely used)
v33Name-based UUID (MD5)
v44Random UUID (most common)
v55Name-based UUID (SHA-1)
v66Time-ordered UUID (RFC 9562)
v77Time-ordered random UUID (RFC 9562)

Variant Bits

The variant is encoded in the 17th character (2-3 bits):

  • Variant 10 (8, 9, a, b): Standard UUID variant (most common)
  • Variant 110 (c, d): Microsoft GUID variant
  • Variant 1110 (e): Reserved for future use
  • Variant 1111 (f): Reserved for future use

UUID Versions Explained

UUID v1 (Time-based)

Characteristics:

  • Based on MAC address and timestamp
  • Contains timestamp information
  • Can be traced back to creation time
  • Not recommended for privacy-sensitive applications

Format:

time_low-time_mid-time_high_and_version-clock_seq_high_and_reserved-clock_seq_low-node

Use cases:

  • Legacy systems
  • When temporal ordering is needed
  • Systems that need to extract creation time

Example:

6ba7b810-9dad-11d1-80b4-00c04fd430c8

UUID v3 (Name-based, MD5)

Characteristics:

  • Deterministic: Same namespace + name = same UUID
  • Uses MD5 hashing (deprecated)
  • Not cryptographically secure
  • Prefer v5 over v3

Format:

hash(namespace_uuid + name)

Namespaces:

  • DNS: 6ba7b810-9dad-11d1-80b4-00c04fd430c8
  • URL: 6ba7b811-9dad-11d1-80b4-00c04fd430c8
  • OID: 6ba7b812-9dad-11d1-80b4-00c04fd430c8
  • X.500: 6ba7b814-9dad-11d1-80b4-00c04fd430c8

Use cases:

  • Legacy systems requiring MD5
  • When deterministic UUIDs are needed (not recommended)

Example:

// Same input always produces same UUID
uuid.v3('dns', 'example.com') // Always: 9073926b-929f-31c2-aa52-f5a5b9e8c123

UUID v4 (Random)

Characteristics:

  • Most commonly used version
  • Cryptographically random
  • No embedded information (timestamp, MAC address)
  • Best for privacy
  • Collision probability is extremely low

Format:

random-random-4xxx-random-random

Use cases:

  • Primary keys in databases
  • API resource identifiers
  • Session tokens
  • File naming
  • Most general-purpose unique identifiers

Example:

550e8400-e29b-41d4-a716-446655440000

Collision probability:

  • For 1 billion UUIDs: ~0.00000006% chance of collision
  • Practically zero for most applications

UUID v5 (Name-based, SHA-1)

Characteristics:

  • Deterministic: Same namespace + name = same UUID
  • Uses SHA-1 hashing (more secure than MD5)
  • Preferred over v3
  • Not cryptographically secure (SHA-1 is deprecated)

Format:

hash(namespace_uuid + name)

Use cases:

  • Generating UUIDs from URLs, domain names, or other names
  • When deterministic UUIDs are needed
  • Content addressing
  • Distributed systems needing consistent IDs

Example:

// Same input always produces same UUID
uuid.v5('dns', 'example.com') // Always: 9073926b-929f-51c2-aa52-f5a5b9e8c123

UUID v6 (Time-ordered, RFC 9562)

Characteristics:

  • Similar to v1 but with reordered fields
  • Better for database indexing (time-ordered)
  • Contains timestamp information
  • Newer standard (RFC 9562, 2024)

Format:

time_high-time_mid-time_low_and_version-clock_seq_high_and_reserved-clock_seq_low-node

Use cases:

  • Database primary keys (better indexing than v4)
  • When temporal ordering is important
  • Log entries
  • Event streams

Example:

1e74ba22-7b62-61d1-80b4-00c04fd430c8

UUID v7 (Time-ordered Random, RFC 9562)

Characteristics:

  • Combines Unix timestamp (milliseconds) with randomness
  • Time-ordered for better database performance
  • No MAC address (privacy-friendly)
  • Newer standard (RFC 9562, 2024)
  • Recommended for new applications

Format:

unix_timestamp_ms-random-random-random

Use cases:

  • Modern database primary keys
  • API resource identifiers
  • Event logging
  • When you need time ordering + randomness

Example:

018b0c3a-7b62-7000-8000-123456789abc

When to Use Each Version

VersionUse WhenDon't Use When
v1Legacy systems, need creation timePrivacy-sensitive, modern systems
v3Legacy systems onlyNew projects (use v5 instead)
v4General purpose, privacy importantNeed time ordering, deterministic IDs
v5Need deterministic UUIDs from namesNeed random UUIDs
v6Need time ordering + MAC address infoPrivacy-sensitive, modern systems
v7Modern apps, need time orderingLegacy systems that don't support it

Common Use Cases

1. Database Primary Keys

PostgreSQL:

CREATE TABLE users (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  email VARCHAR(255) UNIQUE NOT NULL,
  created_at TIMESTAMP DEFAULT NOW()
);
 
-- Insert with UUID
INSERT INTO users (id, email) 
VALUES ('550e8400-e29b-41d4-a716-446655440000', 'user@example.com');

MySQL:

CREATE TABLE users (
  id CHAR(36) PRIMARY KEY,
  email VARCHAR(255) UNIQUE NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
 
-- Insert with UUID
INSERT INTO users (id, email) 
VALUES (UUID(), 'user@example.com');

2. REST API Resource Identifiers

Example API:

// GET /api/users/550e8400-e29b-41d4-a716-446655440000
app.get('/api/users/:id', (req, res) => {
  const userId = req.params.id;
  // Validate UUID format
  if (!isValidUuid(userId)) {
    return res.status(400).json({ error: 'Invalid UUID format' });
  }
  // Fetch user...
});

Benefits:

  • Opaque identifiers (don't reveal internal structure)
  • No sequential IDs (prevents enumeration attacks)
  • Globally unique (no conflicts across services)

3. Distributed Systems

Microservices:

// Generate correlation ID for request tracing
const correlationId = generateUuidV4();
 
// Pass through all service calls
fetch('https://api.service.com/data', {
  headers: {
    'X-Correlation-ID': correlationId
  }
});

Event Sourcing:

const event = {
  id: generateUuidV4(),
  type: 'UserCreated',
  aggregateId: generateUuidV4(),
  timestamp: new Date(),
  data: { /* ... */ }
};

4. File Naming

Unique file uploads:

const fileExtension = originalFilename.split('.').pop();
const uniqueFilename = `${generateUuidV4()}.${fileExtension}`;
// Result: 550e8400-e29b-41d4-a716-446655440000.jpg

Benefits:

  • No filename conflicts
  • Opaque (doesn't reveal file content)
  • URL-safe

5. Session Management

Session tokens:

const sessionId = generateUuidV4();
sessions.set(sessionId, {
  userId: user.id,
  createdAt: Date.now(),
  expiresAt: Date.now() + (24 * 60 * 60 * 1000) // 24 hours
});

6. Cloud Resource Naming

AWS S3 buckets:

const bucketName = `my-app-${generateUuidV4()}`;
// Result: my-app-550e8400-e29b-41d4-a716-446655440000

Kubernetes resources:

apiVersion: v1
kind: Secret
metadata:
  name: secret-550e8400-e29b-41d4-a716-446655440000
type: Opaque
data:
  # ...

7. Content Addressing

Using UUID v5 for deterministic IDs:

// Generate consistent UUID from URL
const contentId = generateUuidV5('url', 'https://example.com/article/123');
// Same URL always produces same UUID

UUID Generation in Different Languages

JavaScript/TypeScript

Using crypto API:

function generateUuidV4() {
  const array = new Uint8Array(16);
  crypto.getRandomValues(array);
  
  // Set version (4) and variant bits
  array[6] = (array[6] & 0x0f) | 0x40;
  array[8] = (array[8] & 0x3f) | 0x80;
  
  // Convert to hex string
  const hex = Array.from(array)
    .map(b => b.toString(16).padStart(2, '0'))
    .join('');
  
  return [
    hex.slice(0, 8),
    hex.slice(8, 12),
    hex.slice(12, 16),
    hex.slice(16, 20),
    hex.slice(20, 32),
  ].join('-');
}

Using libraries:

// uuid package
import { v4 as uuidv4, v5 as uuidv5 } from 'uuid';
 
const id = uuidv4();
const nameBasedId = uuidv5('example.com', uuidv5.DNS);

Python

Using uuid module:

import uuid
 
# v4 (random)
id = uuid.uuid4()
print(str(id))  # 550e8400-e29b-41d4-a716-446655440000
 
# v5 (name-based)
id = uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com')
print(str(id))  # 9073926b-929f-51c2-aa52-f5a5b9e8c123
 
# v1 (time-based)
id = uuid.uuid1()

Go

Using google/uuid:

import "github.com/google/uuid"
 
// v4 (random)
id := uuid.New()
fmt.Println(id.String()) // 550e8400-e29b-41d4-a716-446655440000
 
// v5 (name-based)
namespace := uuid.NameSpaceDNS
id := uuid.NewSHA1(namespace, []byte("example.com"))
fmt.Println(id.String())

Java

Using java.util.UUID:

import java.util.UUID;
 
// v4 (random)
UUID id = UUID.randomUUID();
System.out.println(id.toString()); // 550e8400-e29b-41d4-a716-446655440000
 
// v3 (name-based, MD5)
UUID namespace = UUID.fromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8");
UUID id = UUID.nameUUIDFromBytes("example.com".getBytes());

UUID Validation

Format Validation

Regex pattern:

const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
 
function isValidUuid(uuid) {
  return uuidRegex.test(uuid);
}

Validation checks:

  • Format: 8-4-4-4-12 hexadecimal digits
  • Version: Valid version number (1-7)
  • Variant: Valid variant bits

Version Detection

function getUuidVersion(uuid) {
  const hex = uuid.replace(/-/g, '');
  const version = parseInt(hex[12], 16);
  return version;
}
 
getUuidVersion('550e8400-e29b-41d4-a716-446655440000'); // 4

Best Practices

1. Choose the Right Version

  • v4: Default choice for most applications
  • v7: Modern choice when time ordering is beneficial
  • v5: When you need deterministic UUIDs from names
  • v1/v6: Only when you need time-based ordering

2. Database Indexing

UUID v4 (random):

  • Poor for B-tree indexes (random insertion)
  • Consider UUID v7 for better index performance

UUID v7 (time-ordered):

  • Better for database indexes
  • Sequential insertion improves performance

PostgreSQL:

-- v4: Random, poor index performance
CREATE TABLE users (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid()
);
 
-- v7: Time-ordered, better index performance
-- (Requires custom function or application-level generation)

3. Storage Considerations

Binary storage:

  • Store as 16 bytes (binary) instead of 36 characters (string)
  • Saves ~56% storage space
  • Faster comparisons

PostgreSQL:

-- String (36 bytes)
id UUID
 
-- Binary (16 bytes) - if supported
id BYTEA

4. URL Safety

UUIDs are URL-safe:

https://api.example.com/users/550e8400-e29b-41d4-a716-446655440000

No encoding needed (unlike some other ID formats).

5. Privacy Considerations

Avoid v1/v6 for sensitive data:

  • Contains MAC address (v1) or timestamp
  • Can reveal information about creation

Use v4/v7 for privacy:

  • No embedded information
  • Cryptographically random

6. Performance

Generation speed:

  • v4: Fastest (pure random)
  • v7: Fast (timestamp + random)
  • v5: Slower (requires hashing)
  • v1/v6: Moderate (timestamp calculation)

Database performance:

  • v7 > v6 > v1 > v4 (for sequential inserts)
  • v4: Random inserts cause index fragmentation

Common Mistakes to Avoid

1. Using Sequential IDs Instead of UUIDs

Problem:

// Sequential IDs reveal information
GET /api/users/1
GET /api/users/2
GET /api/users/3

Solution:

// UUIDs are opaque
GET /api/users/550e8400-e29b-41d4-a716-446655440000

2. Not Validating UUID Format

Problem:

// No validation
const userId = req.params.id;
db.query('SELECT * FROM users WHERE id = ?', [userId]);

Solution:

// Validate format
if (!isValidUuid(userId)) {
  return res.status(400).json({ error: 'Invalid UUID' });
}

3. Using v1 for Privacy-Sensitive Data

Problem:

// v1 contains MAC address
const userId = generateUuidV1(); // Can be traced

Solution:

// Use v4 for privacy
const userId = generateUuidV4(); // No embedded info

4. Storing as String Instead of Binary

Problem:

-- 36 bytes per UUID
id VARCHAR(36)

Solution:

-- 16 bytes per UUID (if supported)
id UUID  -- or BINARY(16)

5. Not Considering Database Performance

Problem:

-- Random UUIDs cause index fragmentation
CREATE TABLE users (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid() -- v4
);

Solution:

-- Use time-ordered UUIDs (v7) for better performance
-- Or use application-level generation with v7

Frequently Asked Questions

What's the difference between UUID and GUID?

UUID and GUID are essentially the same thing:

  • UUID: Standard term (RFC 4122)
  • GUID: Microsoft's term (Globally Unique Identifier)

Both refer to the same 128-bit identifier format.

Can UUIDs collide?

Theoretically: Yes, but the probability is extremely low.

Practically: For 1 billion UUIDs, collision probability is ~0.00000006%. For most applications, collisions are not a concern.

Should I use UUIDs as primary keys?

Pros:

  • Globally unique
  • Opaque (don't reveal information)
  • No coordination needed

Cons:

  • Larger than integers (16 bytes vs 4-8 bytes)
  • Slower indexing (for random UUIDs)
  • Less human-readable

Recommendation: Use UUIDs when you need global uniqueness or are building distributed systems. Consider UUID v7 for better database performance.

What's the difference between v4 and v7?

  • v4: Pure random, no time information
  • v7: Time-ordered random, contains Unix timestamp

v7 advantages:

  • Better database index performance
  • Can extract creation time
  • Still privacy-friendly (no MAC address)

Can I extract the creation time from a UUID?

v1/v6: Yes, timestamp is embedded v7: Yes, Unix timestamp (milliseconds) is embedded v4: No, purely random v3/v5: No, based on namespace + name

Are UUIDs secure?

v4/v7: Cryptographically random, suitable for security-sensitive applications v3/v5: Not cryptographically secure (MD5/SHA-1 are deprecated) v1/v6: Contain MAC address, not recommended for privacy

How do I convert UUID to binary?

JavaScript:

function uuidToBinary(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;
}

PostgreSQL:

-- Convert to binary
SELECT uuid_send('550e8400-e29b-41d4-a716-446655440000'::uuid);

Additional Resources