How to Generate a UUID Online (And When You Should Use One)
This guide has a free tool → Open UUID Generator
How to Generate a UUID Online (And When You Should Use One)
A UUID (Universally Unique Identifier) is a 128-bit label used to identify information in computer systems. It looks like this:
550e8400-e29b-41d4-a716-446655440000That is 32 hexadecimal digits displayed in five groups separated by hyphens, following the pattern 8-4-4-4-12. The total number of possible UUIDs is 2^128 - roughly 340 undecillion. To put that in perspective, if you generated one billion UUIDs per second, it would take over ten billion years before you started running out of the UUID space. The odds of generating two identical UUIDs are so low that you can treat them as unique without any coordination between systems.
This is precisely why UUIDs became a foundational primitive in software engineering: they let multiple, uncoordinated systems all generate identifiers independently while remaining effectively guaranteed to never collide.
UUID Generator
Free online UUID generator - generate unique UUIDs (v4) for your applications
Hash Generator
Free online hash generator - generate MD5, SHA-1, SHA-256 hashes from any input text
API Mock Response Generator
Free online API mock response generator - generate mock API responses for testing
The Anatomy of a UUID
Every UUID follows a precise structure. Take this example:
f47ac10b-58cc-4372-a567-0e02b2c3d479
^ ^
| |
version nibble variant nibbleThe fifth nibble of the third group indicates the UUID version. The first nibble of the fourth group is the variant, which indicates the encoding format. For version 4 UUIDs, you will always see a 4 in the version position and an 8, 9, a, or b in the variant position.
Breaking Down the Groups
| Group | Length | Example |
|---|---|---|
| Time-low | 8 hex chars | f47ac10b |
| Time-mid | 4 hex chars | 58cc |
| Time-high-and-version | 4 hex chars | 4372 |
| Clock-seq-and-reserved | 4 hex chars | a567 |
| Node | 12 hex chars | 0e02b2c3d479 |
In a v4 UUID, the names of these groups are misleading - they are filled with random data, not actual time or node information. The groups are purely a display convention inherited from the v1 specification.
UUID Versions: v1, v3, v4, v5, and v7
Not all UUIDs are created the same way. The version determines how the UUID is generated and what information it contains.
UUID v1 (Time-Based)
Generated from the current timestamp and the MAC address of the machine. This means:
- UUIDs are roughly sortable by creation time
- Two UUIDs from the same machine will never collide
- The MAC address is embedded, which can be a privacy concern in many contexts
Example v1 UUID:
6ba7b810-9dad-11d1-80b4-00c04fd430c8The 1 in position 13 indicates version 1. The leading portion of the UUID encodes a 60-bit timestamp representing 100-nanosecond intervals since October 15, 1582 (the date of the Gregorian calendar reform, a historical quirk of the UUID specification).
When to use v1: High-throughput systems where temporal ordering of identifiers helps with index performance (B-tree databases cluster nearby timestamps on the same page). However, v7 is now preferred over v1 for time-ordered identifiers.
UUID v3 (Name-Based, MD5)
Generated by hashing a namespace UUID and a name using MD5. Given the same namespace and name, you always get the same UUID. This makes v3 UUIDs deterministic.
import uuid
namespace = uuid.NAMESPACE_URL
name = "https://example.com"
result = uuid.uuid3(namespace, name)
# Always produces the same output for the same inputWhen to use v3: When you need to derive a stable UUID from some canonical string, like a URL or a username. Note: v5 is preferred over v3 because it uses SHA-1 instead of MD5.
UUID v4 (Random)
Generated from random or pseudo-random numbers. This is the most commonly used version because:
- No information about the machine or time is leaked
- Simple to generate - just 122 random bits (6 bits are used for version and variant)
- Supported by every language and platform
- Privacy-friendly: no device fingerprinting
Example v4 UUID:
550e8400-e29b-41d4-a716-446655440000When in doubt, use v4. It is the default in most libraries and the safest general-purpose choice.
UUID v5 (Name-Based, SHA-1)
Like v3, but uses SHA-1 instead of MD5. SHA-1 is more collision-resistant than MD5, making v5 the preferred choice when you need deterministic, name-derived UUIDs.
// Using the 'uuid' npm package
import { v5 as uuidv5 } from 'uuid';
const MY_NAMESPACE = '1b671a64-40d5-491e-99b0-da01ff1f3341';
const userId = uuidv5('user@example.com', MY_NAMESPACE);
// Always produces the same UUID for the same email + namespaceWhen to use v5: Stable IDs derived from natural keys. For example, generating a consistent UUID for a user based on their email address, so you can reference them in multiple systems without storing a mapping.
UUID v7 (Time-Ordered Random)
A newer version (RFC 9562, finalized 2024) that combines the sortability of v1 with the randomness of v4. The first 48 bits encode a Unix timestamp in milliseconds, followed by random bits.
018e0cf3-dc01-7b6d-9d2c-3b5a1fa35bde
^^^^^^^^^^^^^^^^^
Unix timestamp (ms)Why v7 matters: UUID v4 is random, which means inserting UUIDs into a sorted index (like a B-tree primary key) causes random page splits and poor write performance at scale. UUID v7 IDs are monotonically increasing, so they insert at the end of the index - exactly like auto-increment but globally unique.
When to use v7: New systems that use UUIDs as primary keys, especially with PostgreSQL or MySQL at scale.
When to Use UUIDs vs Auto-Increment IDs
Auto-increment IDs (1, 2, 3, ...) are simple and compact. UUIDs are larger and less human-readable. Here is a structured comparison:
| Property | Auto-Increment | UUID v4 | UUID v7 |
|---|---|---|---|
| Storage size | 4 bytes (INT) | 16 bytes | 16 bytes |
| Human-readable | Yes (#1042) | No | No |
| Globally unique | No | Yes | Yes |
| Requires coordination | Yes (DB sequence) | No | No |
| Sortable | Yes | No | Yes |
| Reveals count | Yes (security risk) | No | No |
| Offline generation | No | Yes | Yes |
| Index performance | Excellent | Poor at scale | Good |
Use Auto-Increment IDs When:
- You have a single database and will never need to merge data from another system
- You need compact, human-readable IDs (like order number #1042 in a customer email)
- Storage efficiency is critical - INT is 4 bytes vs 16 bytes for a UUID
- The sequential nature does not create a security vulnerability in your context
Use UUIDs When:
Distributed systems - multiple services or databases need to generate IDs independently without coordination. A UUID generated on one microservice will never collide with one generated on another, even without any communication between them.
Security - you do not want users to guess valid IDs by incrementing (/users/1, /users/2, /users/3). If /users/1 is valid, a malicious user knows there are at least N users where N is your largest ID. UUIDs make enumeration attacks impractical.
Data merging - combining datasets from different sources, importing data from a partner, or merging databases after an acquisition. Auto-increment IDs will collide; UUIDs will not.
Offline-first apps - clients need to create records locally before they sync to a server. A mobile app that creates a new note needs an ID for that note immediately, without waiting for a round-trip to the server. UUIDs make this trivial.
Public APIs - exposing internal sequential IDs in your API leaks your data volume and growth rate. A competitor could track how many orders you process per day just by creating accounts and placing orders.
Event-driven architectures - events in Kafka, SQS, or similar systems often carry identifiers. UUIDs keep producers and consumers decoupled.
Most modern applications use UUIDs for at least some of their identifiers, especially for resources exposed in URLs or APIs.
How to Generate UUIDs in Code
Here is how you generate UUIDs programmatically in the most common languages and environments.
JavaScript / Node.js
// Node.js (built-in since v14.17) - no dependencies required
const { randomUUID } = require('crypto');
console.log(randomUUID());
// Output: 'f47ac10b-58cc-4372-a567-0e02b2c3d479'
// Using the Web Crypto API in the browser
console.log(crypto.randomUUID());
// Same output format - cryptographically random v4
// Using the 'uuid' npm package for more version support
import { v1, v4, v5, v7 } from 'uuid';
console.log(v4()); // Random UUID v4
console.log(v7()); // Time-ordered UUID v7TypeScript
// In TypeScript with the uuid package
import { v4 as uuidv4, v7 as uuidv7 } from 'uuid';
interface User {
id: string;
name: string;
email: string;
}
function createUser(name: string, email: string): User {
return {
id: uuidv4(), // or uuidv7() for time-ordered
name,
email,
};
}Python
import uuid
# Version 4 (random) - most common
print(uuid.uuid4())
# Output: UUID('550e8400-e29b-41d4-a716-446655440000')
# As a string
print(str(uuid.uuid4()))
# Output: '550e8400-e29b-41d4-a716-446655440000'
# Version 1 (time-based)
print(uuid.uuid1())
# Version 5 (name-based with SHA-1)
namespace = uuid.NAMESPACE_URL
name_uuid = uuid.uuid5(namespace, 'https://example.com')
print(name_uuid)
# Version 4 as bytes (for binary storage)
raw_bytes = uuid.uuid4().bytes
print(len(raw_bytes)) # 16Go
package main
import (
"fmt"
"github.com/google/uuid"
)
func main() {
// Version 4 (random)
id := uuid.New()
fmt.Println(id.String())
// Parse a UUID from a string
parsed, err := uuid.Parse("550e8400-e29b-41d4-a716-446655440000")
if err != nil {
panic(err)
}
fmt.Println(parsed.Version()) // 4
// Validate a UUID string
_, err = uuid.Parse(someInput)
if err != nil {
fmt.Println("Invalid UUID")
}
}Rust
use uuid::Uuid;
fn main() {
// Version 4 (random)
let id = Uuid::new_v4();
println!("{}", id); // 550e8400-e29b-41d4-a716-446655440000
// Hyphenated (default)
println!("{}", id.hyphenated());
// Simple (no hyphens)
println!("{}", id.simple());
// 550e8400e29b41d4a716446655440000
// As URN
println!("{}", id.urn());
// urn:uuid:550e8400-e29b-41d4-a716-446655440000
// Parse from string
let parsed = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
}PHP
<?php
// PHP 8.1+ has a built-in Uuid class (via Symfony component)
// Most common approach uses ramsey/uuid
use Ramsey\Uuid\Uuid;
$uuid = Uuid::uuid4();
echo $uuid->toString();
// 550e8400-e29b-41d4-a716-446655440000
// Simpler approach for PHP 7+
function generateUUIDv4(): string {
$data = random_bytes(16);
$data[6] = chr(ord($data[6]) & 0x0f | 0x40);
$data[8] = chr(ord($data[8]) & 0x3f | 0x80);
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}Java
import java.util.UUID;
public class UUIDExample {
public static void main(String[] args) {
// Version 4 (random)
UUID uuid = UUID.randomUUID();
System.out.println(uuid.toString());
// Parse a UUID
UUID parsed = UUID.fromString("550e8400-e29b-41d4-a716-446655440000");
System.out.println(parsed.version()); // 4
System.out.println(parsed.variant()); // 2
// Generate from name (v3)
UUID v3 = UUID.nameUUIDFromBytes("my-name".getBytes());
}
}C#
// C# has built-in UUID (Guid) support
using System;
// Generate a new random UUID
Guid id = Guid.NewGuid();
Console.WriteLine(id.ToString());
// Output: 550e8400-e29b-41d4-a716-446655440000
// Different format options
Console.WriteLine(id.ToString("N")); // No hyphens
Console.WriteLine(id.ToString("B")); // With braces
Console.WriteLine(id.ToString("P")); // With parentheses
// Parse from string
Guid parsed = Guid.Parse("550e8400-e29b-41d4-a716-446655440000");
bool isValid = Guid.TryParse(input, out Guid result);SQL (PostgreSQL and MySQL)
-- PostgreSQL: built-in UUID generation
SELECT gen_random_uuid();
-- Uses pgcrypto extension: SELECT uuid_generate_v4();
-- Use UUID as primary key
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL
);
-- MySQL 8.0+
SELECT UUID(); -- Generates UUID v1
-- For UUID v4, use UUID() and strip the format-specific bits,
-- or use a stored function
-- MySQL: store as BINARY(16) for efficiency
CREATE TABLE users (
id BINARY(16) PRIMARY KEY DEFAULT (UUID_TO_BIN(UUID(), 1)),
name VARCHAR(255) NOT NULL
);
-- Retrieve as string
SELECT BIN_TO_UUID(id, 1) FROM users;Storing UUIDs in Databases
How you store UUIDs significantly affects query performance and storage overhead.
PostgreSQL: Use the UUID Native Type
-- Correct: native UUID type
CREATE TABLE orders (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Wrong: storing as text wastes space and is slower to index
CREATE TABLE orders (
id VARCHAR(36) PRIMARY KEY, -- Do this
-- ...
);The native UUID type in PostgreSQL stores the value as 16 bytes internally, compared to 36 bytes for a VARCHAR(36). This means 55% less storage and faster comparisons.
MySQL: Use BINARY(16)
MySQL does not have a native UUID type. The best approach is to store as BINARY(16) and use the built-in UUID_TO_BIN() / BIN_TO_UUID() functions, with the swap flag enabled to improve index locality for v1 UUIDs.
-- Insert
INSERT INTO users (id, name)
VALUES (UUID_TO_BIN(UUID(), 1), 'Alice');
-- Query by UUID string
SELECT * FROM users
WHERE id = UUID_TO_BIN('550e8400-e29b-41d4-a716-446655440000', 1);MongoDB: Use the Native UUID Type
MongoDB supports UUID as a BSON subtype. Use the UUID() constructor, not a plain string:
db.users.insertOne({
_id: new UUID(), // Stored as BSON binary subtype 4
name: "Alice"
});SQLite: Store as TEXT or BLOB
SQLite has no UUID type. Use TEXT (36 chars) for readability or BLOB (16 bytes) for efficiency:
-- Readable
CREATE TABLE users (
id TEXT PRIMARY KEY CHECK(length(id) = 36),
name TEXT NOT NULL
);Common UUID Mistakes
Storing as VARCHAR Instead of a Native UUID Type
If your database supports a native UUID type (PostgreSQL, MySQL 8+), use it. Storing UUIDs as VARCHAR(36) wastes space and is slower to index. In PostgreSQL, the native type uses 16 bytes; VARCHAR(36) uses 36 bytes plus overhead.
Using v4 UUIDs as Primary Keys in MySQL with InnoDB at Scale
InnoDB stores rows in primary key order (clustered index). Random v4 UUIDs cause frequent B-tree page splits and cache thrashing because new rows insert at random positions in the index. At small scales (millions of rows), this is not noticeable. At hundreds of millions of rows, you will see dramatic write performance degradation.
Solutions:
- Use UUID v7 (time-ordered) - inserts near the end of the index
- Store v4 UUIDs as BINARY(16) with UUID_TO_BIN's swap flag (swaps time bytes for better locality with v1)
- Use a separate sequential ID as primary key and UUID as a secondary indexed column
-- Better MySQL pattern at scale
CREATE TABLE orders (
id BIGINT AUTO_INCREMENT PRIMARY KEY, -- Fast clustered inserts
uuid BINARY(16) UNIQUE NOT NULL DEFAULT (UUID_TO_BIN(UUID(), 1)), -- For API exposure
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);Assuming UUIDs Are Secret
UUIDs are unique, not secret. Do not use a UUID as an authentication token, a password reset link, or a session token without additional security measures. Anyone who sees a UUID can use it if there is no other access control. They are identifiers, not credentials.
For secure tokens, use a cryptographically random value from your platform's secure random source, and make it significantly longer than a UUID (32 or more bytes of random data, encoded as hex or base64).
Not Validating UUIDs on Input
If your API accepts UUIDs as input (query parameters, path parameters, request bodies), validate them before using them in queries. An invalid UUID passed to a database will either error or behave unexpectedly.
// Node.js validation
function isValidUUID(uuid) {
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-7][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
return uuidRegex.test(uuid);
}
// Or use the 'uuid' package
import { validate } from 'uuid';
if (!validate(req.params.id)) {
return res.status(400).json({ error: 'Invalid UUID' });
}Generating UUIDs on the Client for Sensitive Resources
For resources where predictability matters (financial transactions, access tokens), generate UUIDs server-side or verify client-provided UUIDs before trusting them. A malicious client could pass a carefully chosen UUID that causes a collision if your collision detection is weak.
UUID Formats and Representations
The same UUID can be represented in multiple ways:
| Format | Example |
|---|---|
| Standard (hyphenated) | 550e8400-e29b-41d4-a716-446655440000 |
| Simple (no hyphens) | 550e8400e29b41d4a716446655440000 |
| URN | urn:uuid:550e8400-e29b-41d4-a716-446655440000 |
| Uppercase | 550E8400-E29B-41D4-A716-446655440000 |
| Braces (Windows GUID style) | {550e8400-e29b-41d4-a716-446655440000} |
| Binary | 16 bytes: \x55\x0e\x84\x00... |
All of these represent the same UUID. Stick to the standard hyphenated lowercase format unless your platform has a specific convention.
Working With UUIDs in React and Next.js
// Generating UUIDs in a Next.js API route
import { randomUUID } from 'crypto';
import type { NextApiRequest, NextApiResponse } from 'next';
export default function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === 'POST') {
const newItem = {
id: randomUUID(),
...req.body,
createdAt: new Date().toISOString(),
};
// Save to database...
res.status(201).json(newItem);
}
}// Client-side UUID generation for optimistic updates
import { v4 as uuidv4 } from 'uuid';
function TodoList() {
const [todos, setTodos] = useState<Todo[]>([]);
const addTodo = (text: string) => {
const newTodo = {
id: uuidv4(), // Client-generated UUID
text,
completed: false,
synced: false, // Not yet saved to server
};
setTodos(prev => [...prev, newTodo]); // Optimistic update
saveTodoToServer(newTodo); // Fire and forget
};
}UUID Collision Probability: The Math
The probability of a UUID v4 collision is vanishingly small. Here is how to think about it:
A UUID v4 has 122 random bits (the other 6 are used for version and variant). The number of possible unique values is 2^122, which is approximately 5.3 × 10^36.
To have a 50% probability of at least one collision (the birthday problem), you would need to generate approximately:
sqrt(2 × ln(2) × 2^122) ≈ 2.71 × 10^18 UUIDsThat is 2.71 quintillion UUIDs. If your system generates one million UUIDs per second, you would need to run for 85,000 years before reaching a 50% collision probability.
In practice, UUID v4 is safe for any application. The rare exceptions are cryptographic systems where even theoretical collision risk is unacceptable - use SHA-256 or stronger there.
Generating UUIDs From the Command Line
# Linux (via uuidgen)
uuidgen
# Output: 550e8400-e29b-41d4-a716-446655440000
# macOS (same command)
uuidgen
# Generate 10 UUIDs
for i in $(seq 1 10); do uuidgen; done
# Generate UUID v4 specifically
uuidgen --random
# Generate UUID v1 (time-based)
uuidgen --time
# Python one-liner
python3 -c "import uuid; print(uuid.uuid4())"
# Node.js one-liner
node -e "const {randomUUID}=require('crypto'); console.log(randomUUID())"UUID vs ULID vs NanoID
UUID is not the only option for unique identifiers. Here is how the main alternatives compare:
| Feature | UUID v4 | UUID v7 | ULID | NanoID |
|---|---|---|---|---|
| Length (chars) | 36 | 36 | 26 | 21 (configurable) |
| Sortable | No | Yes | Yes | No |
| URL-safe | No (hyphens) | No | Yes | Yes |
| Spec standardized | Yes (RFC 4122) | Yes (RFC 9562) | Community | Community |
| Time component | No | Yes | Yes | No |
| Language support | Universal | Growing | Good | Good |
| Collision risk | Negligible | Negligible | Negligible | Configurable |
ULID (Universally Unique Lexicographically Sortable Identifier) combines a 48-bit timestamp with 80 random bits, encoded in Crockford's Base32 for URL safety. It looks like 01ARZ3NDEKTSV4RRFFQ69G5FAV.
NanoID is a smaller, faster alternative that generates URL-friendly IDs like V1StGXR8_Z5jdHi6B-myT. Its default 21-character length has a collision probability comparable to UUID v4.
Choose based on your needs:
- Need a universal standard? UUID v4 or v7.
- Need URL-safe + sortable? ULID.
- Need shortest possible? NanoID.
- Need to insert into a database at high write volume? UUID v7 or ULID.
How to Use ToolBox to Generate UUIDs
The UUID Generator on ToolBox generates cryptographically random v4 UUIDs using the Web Crypto API - the same API browsers use for TLS and other security operations. Your UUIDs are never sent to any server.
Step 1: Open the Generator
Navigate to ToolBox UUID Generator. UUIDs are ready the moment the page loads.
Step 2: Configure the Count
Choose how many UUIDs to generate. You can generate individual UUIDs on demand or batch-generate dozens at once for seeding databases or test fixtures.
Step 3: Copy and Use
Click any UUID to copy it to your clipboard, or copy all of them at once. The format is always the standard hyphenated lowercase format compatible with all databases and libraries.
Privacy Note
All generation happens locally in your browser. The Web Crypto API uses the operating system's entropy source (OS-level CSPRNG) to seed the random number generator, ensuring each UUID is cryptographically unpredictable.
Real-World UUID Use Cases
Database Primary Keys
-- PostgreSQL schema
CREATE TABLE articles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
title TEXT NOT NULL,
slug TEXT UNIQUE NOT NULL,
content TEXT,
author_id UUID REFERENCES users(id),
published_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);API Resources
// Express.js API endpoint
app.get('/api/articles/:id', async (req, res) => {
const { id } = req.params;
// Validate UUID before database query
if (!validate(id)) {
return res.status(400).json({ error: 'Invalid article ID' });
}
const article = await db.articles.findOne({ id });
if (!article) {
return res.status(404).json({ error: 'Article not found' });
}
res.json(article);
});Idempotency Keys
Idempotency keys prevent duplicate processing when a request is retried:
// Client: generate an idempotency key for this specific operation
const idempotencyKey = uuidv4();
// Send with the request
await fetch('/api/payments', {
method: 'POST',
headers: {
'Idempotency-Key': idempotencyKey,
'Content-Type': 'application/json',
},
body: JSON.stringify({ amount: 9900, currency: 'usd' }),
});
// Server: if this key was already processed, return the cached result
// instead of charging the card againFile and Asset Naming
// Prevent filename collisions when accepting file uploads
const extension = path.extname(originalFilename);
const storedFilename = `${uuidv4()}${extension}`;
// e.g., '550e8400-e29b-41d4-a716-446655440000.jpg'
// Users cannot predict other users' filenamesCorrelation IDs for Distributed Tracing
// Middleware that adds a unique request ID for tracing across services
app.use((req, res, next) => {
req.requestId = req.headers['x-request-id'] || randomUUID();
res.setHeader('x-request-id', req.requestId);
logger.info({ requestId: req.requestId, path: req.path, method: req.method });
next();
});Try It Free
Open the UUID Generator and generate cryptographically random UUIDs instantly in your browser. Free, private, no signup required.
Need to hash those UUIDs for use in a checksum or cache key? Try the Hash Generator. Building an API that accepts and validates UUIDs? Generate realistic mock API responses with the API Mock Response Generator. Need random test data with UUIDs embedded? Use the Dummy Data Generator to create complete fixtures.
You might also like
Want higher limits, batch processing, and AI tools?