· By DevToolHub Team

UUID vs GUID: Versions, Differences, and When to Use Each

If you’ve ever needed a unique identifier — for a database row, an API resource, a file, or a distributed system event — you’ve likely encountered both “UUID” and “GUID.” Are they different things? Which version should you use? Let’s clear it up.

UUID vs GUID: The Same Thing

UUID (Universally Unique Identifier) and GUID (Globally Unique Identifier) are the same thing. UUID is the standard term defined in RFC 4122 (and its successor RFC 9562), while GUID is Microsoft’s name for the same concept. The format, generation algorithms, and uniqueness guarantees are identical.

The standard format is 32 hexadecimal digits displayed in five groups separated by hyphens:

550e8400-e29b-41d4-a716-446655440000

This gives 2^128 possible values — approximately 3.4 × 10^38 unique identifiers.

UUID Versions

Not all UUIDs are created equal. The version number (the first digit of the third group) tells you how it was generated:

Version 1 — Timestamp + MAC Address

Combines a 60-bit timestamp (100-nanosecond intervals since October 15, 1582) with the machine’s MAC address.

  • Pro: Time-ordered, contains creation metadata
  • Con: Leaks the creator’s MAC address (privacy concern), requires access to system clock and network interface
  • Use case: Legacy systems that need time-ordered IDs

Version 4 — Random

Generated entirely from random or pseudo-random numbers (122 random bits).

  • Pro: Simple, no dependencies, no information leakage
  • Con: Not sortable by creation time, random distribution hurts database index performance
  • Use case: General-purpose identifiers, session tokens, API keys
  • Collision risk: ~50% chance of one collision after generating 2.71 × 10^18 UUIDs

Version 7 — Timestamp + Random (NEW)

The newest version (RFC 9562, 2024). Embeds a Unix timestamp in milliseconds in the first 48 bits, followed by random data.

  • Pro: Time-sortable, no MAC address leakage, excellent for database primary keys
  • Con: Newer standard, not yet universally supported
  • Use case: Database primary keys (especially B-tree indexes), event IDs, anywhere you need both uniqueness and time ordering

Which Version Should You Use?

Use caseRecommended version
Database primary key (SQL)v7 — sortable, great index locality
Database primary key (NoSQL)v7 or v4 — depends on the database
API resource identifierv4 — simple, no information leakage
Session/correlation IDv4 — unpredictable, random
Distributed event orderingv7 — time-sortable across services
Legacy system compatibilityv1 or v4 — depends on what the system expects

Code Examples

JavaScript

// UUID v4 (built-in, no library needed)
crypto.randomUUID()
// "3b241101-e2bb-4d7a-8613-e0b2a4f9b264"

// UUID v7 (using the 'uuid' package)
import { v7 as uuidv7 } from 'uuid';
uuidv7()
// "018e5b6c-d3a0-7f32-b5e1-4a9c3f2d1b08"

// Validate a UUID
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
UUID_REGEX.test('550e8400-e29b-41d4-a716-446655440000') // true

Python

import uuid

# UUID v4 (random)
uuid.uuid4()
# UUID('a3b45c78-1234-4def-8abc-9e8f7a6b5c4d')

# UUID v1 (timestamp + MAC)
uuid.uuid1()
# UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')

# Parse and validate
try:
    parsed = uuid.UUID('550e8400-e29b-41d4-a716-446655440000')
    print(parsed.version)  # 4
except ValueError:
    print("Invalid UUID")

# UUID to string and back
my_uuid = uuid.uuid4()
as_string = str(my_uuid)       # '3b241101-e2bb-4d7a-8613-e0b2a4f9b264'
as_bytes = my_uuid.bytes        # b'\x3b\x24\x11\x01...' (16 bytes)

Go

import "github.com/google/uuid"

// UUID v4
id := uuid.New()
fmt.Println(id.String()) // "3b241101-e2bb-4d7a-8613-e0b2a4f9b264"

// UUID v7
id7, _ := uuid.NewV7()
fmt.Println(id7.String())

// Parse and validate
parsed, err := uuid.Parse("550e8400-e29b-41d4-a716-446655440000")
if err != nil {
    log.Fatal("invalid UUID")
}
fmt.Println(parsed.Version()) // 4

SQL (PostgreSQL)

-- UUID v4 (built-in since PostgreSQL 13)
SELECT gen_random_uuid();

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

-- For UUID v7, use the pg_uuidv7 extension
CREATE EXTENSION IF NOT EXISTS pg_uuidv7;
CREATE TABLE events (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v7(),
    payload JSONB
);

Bash

# Generate UUID v4 (Linux)
cat /proc/sys/kernel/random/uuid

# Generate UUID v4 (macOS/Linux with uuidgen)
uuidgen

# Generate UUID v4 with Python one-liner
python3 -c "import uuid; print(uuid.uuid4())"

UUIDs as Database Primary Keys

This is where the version choice matters most. With B-tree indexes (used by PostgreSQL, MySQL, SQLite), random v4 UUIDs cause index fragmentation because new entries are inserted at random positions in the tree. This leads to more page splits and slower inserts at scale.

V7 UUIDs solve this because their time-ordered prefix means new entries are always appended near the end of the index — similar to auto-increment integers but without coordination.

PostgreSQL tip: Use the gen_random_uuid() function for v4, or use a library like pg_uuidv7 for v7 UUIDs.

UUID String vs Binary Storage

A UUID as a string (550e8400-e29b-41d4-a716-446655440000) takes 36 bytes. As binary, it takes only 16 bytes. In databases:

  • PostgreSQL: Use the native uuid type (stored as 16 bytes)
  • MySQL: Use BINARY(16) or CHAR(36) depending on query patterns
  • SQLite: Store as TEXT (no native UUID type)
  • MongoDB: BinData subtype 4 (16 bytes) or string (36 bytes)

Always use the database’s native UUID type when available — it’s more storage-efficient and enables UUID-aware operations.

Alternatives to UUID

FormatLengthSortableUniqueUse case
UUID v436 charsNoYesGeneral purpose
UUID v736 charsYesYesDatabase keys
ULID26 charsYesYesCompact sortable IDs
NanoID21 charsNoYesURL-friendly short IDs
CUID224 charsNoYesSecure, collision-resistant
Snowflake ID18 digitsYesYesTwitter/Discord-style (requires coordinator)

If you need shorter IDs and don’t need RFC compliance, ULID and NanoID are popular alternatives. If you’re in an ecosystem that expects UUIDs (most databases, APIs, and frameworks), stick with UUID v4 or v7.

Try It Yourself

Use our UUID Generator to generate v4 (random) or v7 (sortable) UUIDs instantly — with batch generation for creating multiple UUIDs at once.

You might also find the Hash Generator useful for creating deterministic identifiers from known inputs, or check out how JWT tokens use UUIDs for session identification.

Further Reading

FAQ

Is UUID the same as GUID?
Yes. UUID (Universally Unique Identifier) and GUID (Globally Unique Identifier) are the same thing. UUID is the standard term from RFC 4122/9562, while GUID is Microsoft's name for the same concept. The format, algorithms, and uniqueness guarantees are identical.
Can two UUIDs ever be the same?
Theoretically yes, but practically no. UUID v4 has 122 random bits, giving 5.3 × 10^36 possible values. You'd need to generate about 2.71 × 10^18 (2.71 quintillion) UUIDs before having a 50% chance of a single collision. That's generating 1 billion UUIDs per second for 86 years.
Should I use UUID or auto-increment for database primary keys?
UUID is better for distributed systems (no coordination needed), API-exposed IDs (hides row count), and systems that merge data from multiple sources. Auto-increment is better for single-database apps where you need smaller IDs, faster joins, and simpler debugging. UUID v7 is a good compromise — it's sortable like auto-increment but globally unique like UUID.
Why is UUID v7 better than v4 for databases?
UUID v4 is fully random, causing random insertions into B-tree indexes. This fragments the index and slows inserts at scale. UUID v7 embeds a timestamp in the first 48 bits, so new IDs are always greater than previous ones — they append to the end of the index like auto-increment, but without coordination.
How do I validate if a string is a valid UUID?
A valid UUID matches the pattern: 8-4-4-4-12 hex digits, e.g., 550e8400-e29b-41d4-a716-446655440000. The regex is: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i. Most languages have built-in UUID validation — Python's uuid.UUID() constructor, Java's UUID.fromString(), etc.
uuid guid database distributed-systems programming

Related Tools

Related Articles