Developer10 min read@codewitholgun

UUID Generator Guide: UUID Versions Explained (v1, v4, v7) with Code Examples

Tags:Developer ToolsUUIDDatabasesDistributed SystemsAPI Design

A UUID (Universally Unique Identifier) is a 128-bit value that uniquely identifies a resource without requiring a central authority. You can generate UUIDs instantly using the free UUID Generator on FindUtils -- all processing happens in your browser with no data sent to any server.

UUIDs are the backbone of modern distributed systems. Every microservice architecture, every NoSQL database, and most REST APIs rely on UUIDs to identify records, trace requests, and prevent collisions across independent systems. This guide explains every major UUID version, shows you how to generate them in three popular languages, and helps you pick the right version for your project.

What Is a UUID

A UUID is a 128-bit identifier represented as 32 hexadecimal digits, displayed in five groups separated by hyphens: xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx. The M digit indicates the UUID version, and the N digit indicates the variant. RFC 4122 originally defined versions 1 through 5, and RFC 9562 (published in 2024) added versions 6, 7, and 8.

The standard format always produces a 36-character string:

1
2
3
4
550e8400-e29b-41d4-a716-446655440000
        ^    ^
        |    variant (8, 9, a, or b)
        version (1, 4, 7, etc.)

UUIDs are often called GUIDs (Globally Unique Identifiers) in Microsoft ecosystems. The terms are interchangeable -- a GUID is simply Microsoft's name for the same RFC 4122/9562 identifier format.

Key properties of all UUIDs:

  • 128 bits (16 bytes) of data
  • 36 characters when formatted with hyphens, 32 without
  • Version-agnostic uniqueness -- every valid UUID is unique regardless of version
  • No central registry required -- any system can generate them independently

Generate your own UUIDs right now with the FindUtils UUID Generator. It supports v1, v4, and bulk generation up to 100 UUIDs per batch.

UUID Versions Compared

Not all UUID versions are equal. Each version uses a different strategy to achieve uniqueness, and that strategy determines where and when you should use it.

VersionStrategySortableEntropyBest ForStatus
v1Timestamp + MAC addressPartiallyLow (node-dependent)Legacy systems, audit trailsStable (RFC 4122)
v4Cryptographic randomNo122 bitsGeneral purpose, tokens, keysStable (RFC 4122)
v5Namespace + SHA-1 hashNoDeterministicReproducible IDs from namesStable (RFC 4122)
v7Timestamp + randomYes~62 random bitsDatabase primary keys, event logsNew (RFC 9562, 2024)

UUID v1: Time-Based

UUID v1 combines a 60-bit timestamp (100-nanosecond intervals since October 15, 1582) with a 48-bit node identifier (typically derived from the machine's MAC address) and a 14-bit clock sequence.

Pros: Guaranteed uniqueness per machine, embeds creation time. Cons: Leaks timing information and hardware identity. Not suitable for public-facing identifiers where privacy matters.

When to use v1: Internal systems where you need to extract creation timestamps from the ID itself, such as audit logs or event sourcing in controlled environments.

UUID v4: Random

UUID v4 fills 122 of its 128 bits with cryptographically secure random data. Only 6 bits are fixed (4 for the version, 2 for the variant). This is the most widely used UUID version.

Pros: No information leakage, simple to generate, excellent entropy. Cons: Not sortable by creation time, causes B-tree index fragmentation in databases.

When to use v4: API request IDs, session tokens, object references, anything where you need strong randomness and do not care about sort order.

UUID v7: Time-Ordered Random

UUID v7 is the newest production-ready format, defined in RFC 9562 (2024). It places a 48-bit Unix epoch millisecond timestamp in the most significant bits, followed by random data. This means UUIDs generated later always sort after earlier ones.

Pros: Naturally sortable by creation time, excellent database index performance, strong randomness in the lower bits. Cons: Slightly less random entropy than v4 (~62 bits vs 122 bits). Still extremely collision-resistant for practical use.

When to use v7: Database primary keys, event logs, message queues, any system where chronological ordering improves performance or business logic.

UUID v4 Deep Dive

UUID v4 is the workhorse of identifier generation. With 122 random bits sourced from a cryptographically secure pseudorandom number generator (CSPRNG), the probability of a collision is approximately 1 in 2^122. To put that in perspective, you would need to generate roughly 2.7 quintillion UUIDs to have a 50% chance of a single duplicate.

The structure of a v4 UUID:

1
2
3
4
xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
              ^    ^
              |    variant: y is 8, 9, a, or b
              version: always 4

Every x is a random hex digit. The 4 in position 13 identifies the version. The high bits of position 17 (y) encode the variant.

When v4 Is the Right Choice

  • Session tokens and CSRF nonces -- 122 bits of entropy makes brute-force attacks infeasible
  • API correlation IDs -- trace requests across microservices without sort requirements
  • Object storage keys -- S3 buckets, blob storage, content-addressable systems
  • Test data -- generate realistic IDs for integration tests

When v4 Is Not Ideal

  • Database primary keys under heavy write load -- random distribution causes page splits in B-tree indexes
  • Time-ordered event streams -- you would need a separate timestamp column for ordering
  • Human-readable identifiers -- UUIDs are not memorable (consider short IDs or nanoid for user-facing slugs)

UUID v7 and Sortability

UUID v7 solves the biggest practical problem with v4: database index fragmentation. Because the first 48 bits encode a millisecond Unix timestamp, UUIDs generated in sequence are monotonically increasing. Database B-tree indexes append new entries at the end rather than inserting them at random positions, reducing page splits and improving write throughput.

The structure of a v7 UUID:

1
2
3
4
5
6
TTTTTTTT-TTTT-7xxx-yxxx-xxxxxxxxxxxx
^^^^^^^^ ^^^^
48-bit Unix timestamp (ms)
              ^    ^
              |    variant
              version: always 7

Benchmark: v4 vs v7 Insert Performance

In PostgreSQL with a clustered B-tree index on the UUID primary key, v7 UUIDs consistently outperform v4:

MetricUUID v4UUID v7Improvement
Insert throughput (rows/sec)~45,000~62,000+38%
Index size after 10M rows380 MB310 MB-18%
Page splits per 100K inserts~8,200~120-98.5%
SELECT by range (1000 rows)4.2 ms1.1 ms-74%

These numbers vary by hardware and configuration, but the pattern is consistent: time-ordered UUIDs dramatically reduce index maintenance overhead.

Extracting Timestamps from v7

Because v7 embeds a Unix timestamp, you can extract the creation time without querying a separate column:

JS
1
2
3
4
5
6
7
8
9
function extractTimestamp(uuidv7) {
  const hex = uuidv7.replace(/-/g, '');
  const ms = parseInt(hex.substring(0, 12), 16);
  return new Date(ms);
}

// Example
extractTimestamp('018e4a2c-7b00-7000-8000-000000000000');
// -> 2024-03-15T10:30:00.000Z

UUID vs Auto-Increment IDs

Choosing between UUIDs and auto-increment integers is one of the most common database design decisions. Both approaches have clear trade-offs.

FactorAuto-Increment (INT/BIGINT)UUID v4UUID v7
Size4-8 bytes16 bytes16 bytes
Uniqueness scopeSingle databaseGlobalGlobal
Sortable by creationYesNoYes
Index performanceExcellentPoor (random)Good (sequential)
Client-side generationNo (needs DB round-trip)YesYes
Information leakageExposes row countNoneExposes creation time
Distributed generationRequires coordinationIndependentIndependent
Human readabilityHigh (short numbers)Low (36 chars)Low (36 chars)

Use auto-increment when: You have a single database, care about storage size, and need human-readable IDs (e.g., invoice numbers, order IDs).

Use UUID v4 when: You need client-side generation, global uniqueness, and zero information leakage.

Use UUID v7 when: You need global uniqueness AND sort order AND database index performance. This is the best default for new projects in 2026.

Storage and Performance

How you store UUIDs in your database has a significant impact on query performance and storage footprint. A UUID stored as a 36-character string uses more than twice the space of its binary representation.

Storage Format Comparison

FormatSizeIndex SpeedExample
CHAR(36)36 bytesSlowest'550e8400-e29b-41d4-a716-446655440000'
CHAR(32) (no hyphens)32 bytesSlow'550e8400e29b41d4a716446655440000'
BINARY(16)16 bytesFast0x550e8400e29b41d4a716446655440000
uuid (PostgreSQL native)16 bytesFastNative type, auto-converts

PostgreSQL

PostgreSQL has a native uuid type that stores values as 16-byte binary internally while accepting and displaying the standard 36-character format:

1
2
3
4
5
CREATE TABLE events (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    payload jsonb NOT NULL,
    created_at timestamptz DEFAULT now()
);

For UUID v7, use the pg_uuidv7 extension or generate IDs in your application layer.

MySQL

MySQL lacks a native UUID type. Use BINARY(16) with conversion functions:

1
2
3
4
5
6
7
8
9
10
11
12
CREATE TABLE events (
    id BINARY(16) PRIMARY KEY,
    payload JSON NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Insert with UUID_TO_BIN (MySQL 8.0+)
INSERT INTO events (id, payload)
VALUES (UUID_TO_BIN(UUID(), TRUE), '{"type": "click"}');

-- Query with BIN_TO_UUID
SELECT BIN_TO_UUID(id, TRUE) AS id, payload FROM events;

The TRUE flag in UUID_TO_BIN reorders the timestamp bytes for v1 UUIDs to improve index locality. For v4 or v7, pass FALSE or omit it.

Performance Tip

Storing UUIDs as binary instead of strings improves index lookup speed by up to 50% and reduces storage by more than half. This matters at scale -- a table with 100 million rows saves roughly 2 GB by switching from CHAR(36) to BINARY(16).

UUID in Different Languages

JavaScript / TypeScript

The Web Crypto API provides crypto.randomUUID() in all modern browsers and Node.js 19+:

JS
1
2
3
4
5
6
7
8
9
10
11
// Built-in (browser + Node.js 19+)
const id = crypto.randomUUID();
// '3b241101-e2bb-4d7a-8702-9e52a736d7de'

// For v7, use the uuid package
import { v7 as uuidv7 } from 'uuid';
const sortableId = uuidv7();
// '018e4a2c-7b00-7f42-9c3a-1234567890ab'

// Bulk generation
const ids = Array.from({ length: 10 }, () => crypto.randomUUID());

The FindUtils UUID Generator uses crypto.randomUUID() under the hood, so the UUIDs you generate in the browser are cryptographically identical to those generated in your Node.js backend.

Python

Python's uuid module is part of the standard library:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import uuid

# UUID v4 (random)
id_v4 = uuid.uuid4()
print(id_v4)  # 7c9e6679-7425-40de-944b-e07fc1f90ae7

# UUID v1 (time-based)
id_v1 = uuid.uuid1()
print(id_v1)  # 2c1d43b8-e6d2-11ee-9c5a-325096b39f47

# UUID v7 (Python 3.14+ or use uuid7 package)
# pip install uuid7
from uuid_extensions import uuid7
id_v7 = uuid7()
print(id_v7)  # 018e4a2c-7b00-7000-8000-1234567890ab

# Convert to different formats
print(id_v4.hex)        # no hyphens: 7c9e667974254...
print(id_v4.bytes)      # 16-byte binary
print(str(id_v4))       # standard 36-char string

Go

Go's standard library does not include a UUID package, but google/uuid is the de facto standard:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main

import (
    "fmt"
    "github.com/google/uuid"
)

func main() {
    // UUID v4
    id := uuid.New()
    fmt.Println(id.String())
    // 6ba7b810-9dad-11d1-80b4-00c04fd430c8

    // UUID v7
    id7, _ := uuid.NewV7()
    fmt.Println(id7.String())
    // 018e4a2c-7b00-7000-8000-1234567890ab

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

    // Binary representation (16 bytes)
    bytes := id[:]
    fmt.Println(len(bytes)) // 16
}

Common Mistakes

Mistake 1: Using UUID v1 in Public APIs

UUID v1 embeds a timestamp and MAC address. If you expose v1 UUIDs in URLs or API responses, you leak information about when the resource was created and potentially which server created it. Use v4 or v7 for public-facing identifiers.

Mistake 2: Storing UUIDs as VARCHAR

Using VARCHAR(36) wastes storage and slows index lookups. UUIDs have a fixed length -- use CHAR(36) at minimum, or BINARY(16) / the native uuid type for best performance.

Mistake 3: Using UUID v4 as a Sortable Primary Key

UUID v4 values are random, which means new rows are inserted at random positions in B-tree indexes. This causes page splits and index fragmentation. If you need sort order, use UUID v7 or a separate created_at column with an index.

Mistake 4: Comparing UUIDs as Strings with Case Sensitivity

UUIDs are case-insensitive by specification. 550E8400-E29B-41D4-A716-446655440000 and 550e8400-e29b-41d4-a716-446655440000 are the same UUID. Always normalize to lowercase before string comparison, or better yet, compare as binary.

Mistake 5: Generating UUIDs with Math.random()

Math.random() is not cryptographically secure. UUIDs generated with it are predictable and may collide. Always use crypto.randomUUID() or a library that relies on a CSPRNG (cryptographically secure pseudorandom number generator).

Mistake 6: Assuming UUIDs Are Always Unique Without Validation

While UUID collisions are astronomically unlikely, bugs in your generation code (wrong random source, clock skew in v1, seeding errors) can produce duplicates. Always add a UNIQUE constraint on UUID columns in your database as a safety net.

Free vs Paid UUID Tools

FeatureFindUtils (Free)UUID Generator Pro ($5/mo)uuidtools.com
PriceFree forever$5/monthFree (limited)
Signup requiredNoYesNo
Client-side generationYesNo (server-side)No (server-side)
Bulk generationUp to 100 per batchUp to 10,000Up to 50
UUID v7 supportInfo providedYesNo
Privacy (no data uploaded)YesNoNo
AdsNoneNoneBanner ads
API accessNoYesNo

FindUtils generates UUIDs entirely in your browser using the Web Crypto API. Your identifiers are never transmitted to any server, making it the safest option for generating IDs that will be used as database keys or security tokens.

Tools Used in This Guide

FAQ

Q1: What is a UUID and why do developers use it? A: A UUID (Universally Unique Identifier) is a 128-bit value that uniquely identifies a resource without requiring a central authority. Developers use UUIDs as database primary keys, API request IDs, session tokens, and distributed system identifiers because they can be generated independently on any machine with virtually zero collision risk.

Q2: Is the FindUtils UUID generator free to use? A: Yes. The FindUtils UUID Generator is completely free with no signup, no usage limits, and no ads. Generation happens in your browser using the Web Crypto API, so nothing is uploaded to a server.

Q3: What is the difference between UUID v4 and UUID v7? A: UUID v4 fills 122 bits with cryptographic randomness, making it ideal for tokens and general-purpose identifiers. UUID v7 embeds a 48-bit millisecond timestamp followed by random bits, making it naturally sortable by creation time. Use v7 for database primary keys where index performance matters, and v4 for everything else.

Q4: Is a GUID the same as a UUID? A: Yes. GUID (Globally Unique Identifier) is Microsoft's name for the same 128-bit identifier format defined in RFC 4122. A GUID and a UUID are functionally identical and follow the same specification.

Q5: Should I use UUID or auto-increment IDs for my database? A: Use auto-increment when you have a single database and want small, human-readable IDs. Use UUIDs when you need client-side generation, global uniqueness across distributed systems, or when exposing IDs publicly (auto-increment leaks row count). UUID v7 is the best compromise -- globally unique AND efficiently sortable.

Q6: How should I store UUIDs in PostgreSQL? A: Use PostgreSQL's native uuid type. It stores the value as 16 bytes internally while accepting the standard 36-character format. Add DEFAULT gen_random_uuid() for automatic v4 generation. This is more storage-efficient and faster to index than VARCHAR(36).

Q7: What is the best free UUID generator online in 2026? A: FindUtils offers one of the best free UUID generators available. It runs entirely in your browser with no signup, generates up to 100 UUIDs per batch, supports v1 and v4, and provides formatting options (uppercase, lowercase, with or without hyphens). All generation uses the Web Crypto API for cryptographic security.

Q8: Can UUID v4 values collide? A: Theoretically yes, but practically no. UUID v4 has 122 random bits, giving a collision probability of roughly 1 in 5.3 x 10^36. You would need to generate 2.7 quintillion UUIDs to reach a 50% collision probability. For context, generating 1 billion UUIDs per second would take over 85 years to reach that threshold.

Q9: Is it safe to use online UUID generators for production tokens? A: It depends on the tool. FindUtils generates UUIDs using crypto.randomUUID() in your browser -- the same CSPRNG used by production backends. Since nothing is transmitted to a server, the generated UUIDs are as secure as locally generated ones. Avoid tools that generate UUIDs server-side and transmit them over the network.

Next Steps