UUID v4, ULID, and NanoID: Choosing the Right Unique Identifier
Compare the most popular unique identifier formats — their structure, trade-offs, and which to reach for in different situations.
Why Not Just Use Auto-Increment IDs?
Auto-increment integer IDs (1, 2, 3…) work well in single-database systems. They break down when you need to:
- Generate IDs client-side before a database round-trip
- Merge records from multiple databases without collisions
- Avoid exposing record counts or insertion order to users
- Work in distributed or eventually-consistent systems
UUID, ULID, and NanoID all address these concerns in different ways.
UUID v4
UUID (Universally Unique Identifier) is defined by RFC 4122. Version 4 is randomly generated — 122 bits of random data with 6 bits reserved for version and variant markers.
// Format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
// Where y is 8, 9, a, or b
550e8400-e29b-41d4-a716-446655440000
f47ac10b-58cc-4372-a567-0e02b2c3d479Generating UUID v4 in the browser
// Modern — cryptographically secure
const id = crypto.randomUUID();
// Older fallback
function uuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
const r = crypto.getRandomValues(new Uint8Array(1))[0] % 16;
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
}UUID v4 trade-offs
- Pro — Universally standardized, supported everywhere
- Pro — Practically zero collision probability (2¹²² combinations)
- Con — Random order hurts database B-tree index performance at scale
- Con — 36 characters (with hyphens) is verbose in URLs and logs
ULID (Universally Unique Lexicographically Sortable Identifier)
ULID was designed to address UUID's random ordering problem. Each ULID encodes a millisecond-precision timestamp in the first 48 bits, followed by 80 random bits.
01ARZ3NDEKTSV4RRFFQ69G5FAV
// Structure:
// 01ARZ3NDEK — timestamp (10 chars, 48 bits)
// TSV4RRFFQ69G5FAV — randomness (16 chars, 80 bits)- Pro — Lexicographically sortable (newer IDs sort after older ones)
- Pro — 26 characters vs 36 for UUID
- Pro — Better database index locality than UUID v4
- Con — Not natively supported in browsers; needs a library
- Con — Encodes creation time, which may be a privacy concern
NanoID
NanoID is a small, URL-friendly unique ID library. By default it generates 21 characters using a 64-character alphabet, giving ~126 bits of randomness — comparable to UUID v4.
// Default 21-char output
V1StGXR8_Z5jdHi6B-myT
// Custom length and alphabet
nanoid(10) // Shorter, less entropy
nanoid(32, '0123456789abcdef') // Hex only- Pro — URL-safe by default (no special characters)
- Pro — Configurable length and alphabet
- Pro — Tiny library (~130 bytes minified)
- Con — Not a standard; not natively supported
- Con — Random order (same B-tree issue as UUID v4)
UUID v7 — The Best of Both Worlds
UUID v7 (RFC 9562, 2024) is a newer standard that combines a millisecond timestamp prefix with random bits — giving sortability like ULID while staying within the UUID standard. It is becoming the preferred choice for new database schemas.
// UUID v7 format: timestamp-first
018e57e4-4a0b-7000-b3d9-47c44b2bfc44
// First 12 hex chars = Unix ms timestampQuick Decision Guide
- UUID v4 — Default choice; works everywhere; no dependency needed
- UUID v7 — New projects where database index performance matters
- ULID — When you need sortability and can add a small dependency
- NanoID — Short, URL-safe IDs (session tokens, short links)
- Auto-increment — Simple CRUD apps with a single database
Generate UUIDs instantly
Use our free UUID Generator to create UUID v4 strings in bulk — copy individually or all at once.
Open UUID Generator →