If you have ever looked at a URL like /users/550e8400-e29b-41d4-a716-446655440000 or an API response with an id field that looks like a string of hexadecimal gibberish, you have seen a UUID. They are everywhere in modern software — database primary keys, session tokens, file names, distributed system identifiers. This post explains what they are, why developers use them, and how to generate them reliably.
What Is a UUID?
UUID stands for Universally Unique Identifier. It is a 128-bit number, typically represented as 32 hexadecimal characters grouped by hyphens in the pattern 8-4-4-4-12:
``
550e8400-e29b-41d4-a716-446655440000
`
The name is the spec: a UUID is designed to be unique across space and time, without requiring a central authority to issue or track them. Two different systems can each generate a UUID independently and, statistically, they will never produce the same value.
The probability of two random UUID v4s colliding is roughly 1 in 5.3 × 10³⁶ — for practical purposes, impossible.
UUID Versions
The RFC 4122 spec defines several versions, each using a different generation strategy:
Version 1 (timestamp + MAC address)
Combines the current timestamp with the network interface MAC address. Unique in time, but leaks the machine's hardware identity. Rarely used in new systems for privacy reasons.
Version 3 and Version 5 (namespace + name)
Deterministically generates a UUID from a namespace and a name using MD5 (v3) or SHA-1 (v5). The same inputs always produce the same UUID. Useful for content-addressed IDs where you need reproducibility — for example, generating a stable ID for a URL or a product SKU.
Version 4 (random)
Generates 122 bits of randomness and sets four bits to identify the version. This is the most commonly used version — simple, fast, privacy-safe, and collision-resistant. When someone says "generate a UUID", they almost always mean v4.
Version 7 (timestamp + random, sortable)
A newer addition (RFC 9562), combining a millisecond-precision Unix timestamp in the most significant bits with random bits in the remainder. This makes v7 UUIDs naturally sortable by creation time — a major advantage for database primary keys where index locality matters.
Why Use UUIDs Instead of Auto-Increment IDs?
Sequential integer IDs (id: 1, 2, 3...) are simple and compact, but they have real limitations in distributed or public-facing systems:
No central coordinator needed — with UUIDs, any service, any machine, any offline device can generate a valid ID without checking in with a database. This is essential for microservices, mobile sync, and distributed writes.
Enumeration resistance — sequential IDs make it trivial for an attacker to enumerate all your records: /users/1, /users/2, etc. UUIDs expose nothing about your dataset size or creation order.
Merge safety — when merging data from multiple sources (database migrations, app syncs, multi-tenant systems), UUID primary keys have zero collision risk. Sequential integer keys from two databases will always collide.
The trade-off: UUIDs are 36 characters as strings vs 4–8 bytes for an integer. In a table with millions of rows and UUID-indexed foreign keys, this storage cost and the random nature of v4 UUIDs can fragment B-tree indexes. UUID v7 addresses the index fragmentation problem by being timestamp-sorted.
How to Generate UUIDs
In modern JavaScript (browser and Node.js):
<code>javascript
<p>const id = crypto.randomUUID(); // v4, built-in since Node.js 15 / Chrome 92</p>
</code>
In Python:
<code>python
<p>import uuid</p>
<p>v4 = str(uuid.uuid4()) # random</p>
<p>v5 = str(uuid.uuid5(uuid.NAMESPACE_URL, 'https://example.com')) # deterministic</p>
</code>
In PostgreSQL:
`sql
-- Enable extension once per database
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
-- Use as default column value
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL
);
`
In MySQL/MariaDB:
<code>sql
<p>CREATE TABLE users (</p>
<p>id CHAR(36) PRIMARY KEY DEFAULT (UUID()),</p>
<p>name VARCHAR(255) NOT NULL</p>
<p>);</p>
</code>
Online generator
For quick generation without writing code — when you need a UUID for a config file, a test fixture, or a one-off API call — use the free UUID Generator at SnappyTools. It generates v4 UUIDs in bulk (1–20 at a time), lets you choose the format (standard hyphenated, no hyphens, uppercase), and copies to clipboard instantly.
UUID vs ULID vs NanoID
UUIDs are the standard, but alternatives exist for specific use cases:
ULID (Universally Unique Lexicographically Sortable Identifier)
26-character base32 string, timestamp-prefixed, sortable. Similar goals to UUID v7 but predates it and has wider library support. Good for systems where sort order by creation time matters.
NanoID
URL-safe, configurable length (default 21 chars), uses only A-Za-z0-9_-. Shorter than a UUID, collision-resistant, and more readable in URLs. Popular in JavaScript ecosystems.
When to stick with UUID v4: compatibility with existing systems, database UUID columns, RFC 4122 compliance requirements, any context where "standard UUID" is explicitly expected.
Storing UUIDs in Databases
Store UUIDs as the native UUID type when your database supports it (PostgreSQL UUID, MySQL BINARY(16) with UNHEX(REPLACE(uuid, '-', ''))). This uses 16 bytes instead of 36 and enables efficient index operations.
Avoid storing UUIDs as VARCHAR(36)` — it wastes storage and makes comparisons slower. The string representation is for display and transfer; the binary representation is for storage.
UUIDs are one of those foundational tools that become invisible once you understand them. When you need to generate one quickly — for a test, a config value, or a quick API call — the UUID Generator has you covered without any setup.
Originally published at https://snappytools.app/uuid-generator/