UUID Generator

v4 (random), v7 (time-ordered), v1, NIL — up to 1000 at once

What is a UUID?

A UUID (Universally Unique Identifier) is a 128-bit value that creates globally unique identifiers without a central authority. It is standardized in RFC 4122 (classic) and RFC 9562 (v6/7/8). It is represented as 32 hexadecimal digits in five dash-separated groups.

Which UUID version do I need?

  • v4: random, safe, most common choice for database IDs
  • v7: time-ordered, ideal for database indexes and chronological sorting
  • v1: timestamp + MAC address (legacy, may leak metadata)
  • NIL: all bits zero — placeholder for 'no UUID'

How random are UUIDs?

In UUIDv4, 122 of 128 bits are random (the other 6 encode version and variant). The collision probability is astronomically small: even at one billion UUIDs per second for 85 years, the chance of a collision stays below 50%. In practice, UUIDs are treated as collision-free. This tool uses the Web Crypto API (crypto.getRandomValues) for cryptographically strong randomness.

Anatomy of a UUID: 128 bits, five fields, one standard

A UUID is 128 bits, traditionally written as 32 hex characters with 4 hyphens — 36 chars total. The fields are time_low (8) - time_mid (4) - time_hi_and_version (4) - clock_seq (4) - node (12). The version lives in the first nibble of group three (position 13), the variant in the first nibble of group four (position 17). A v4 UUID is recognized by a 4 at position 13 and a value in {8, 9, a, b} at position 17.

The 2005 standard RFC 4122 defined classic versions 1-5. RFC 9562 (May 2024) superseded it and introduced v6, v7 and v8 as official standards. Before that, v6 and v7 only existed as industry conventions (e.g. ULID, KSUID, Snowflake). The key innovation is v7: 48 bits of Unix milliseconds as a prefix, then 74 bits of randomness — making UUIDs sortable in generation order, a drastic perf win on B-tree indexes in PostgreSQL or MySQL.

Why not a plain auto-increment integer? UUIDs let you generate IDs client-side (no DB round-trip), prevent enumeration attacks (no /api/order/1234 -> 1235) and remain unique across sharding boundaries or distributed systems. Downsides: 16 bytes instead of 4 or 8 per index entry, worse cache locality for v4 (random inserts scatter across the index), poor human readability. v7 significantly mitigates the index downside.

Bit layout and birthday math

How many UUIDs must you generate before a collision becomes likely? Using the birthday approximation, the count for a 50% collision probability is roughly:

n ≈ sqrt(2 * 2^B * ln(2))

where B = effective random bits.

Version   Random bits   50% collision after
---------+-------------+----------------------
v4              122      ~2.7 * 10^18 UUIDs
v7               74      ~1.6 * 10^11 UUIDs (per millisecond bucket)
v1            < 48      seconds under heavy load

UUIDv4 layout (hex):
  xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
               ^    ^
          Version  Variant (y in {8,9,a,b})

Concrete use cases

UUIDs are the standard tool whenever an ID lives outside a single database row. Five typical scenarios:

  • Database primary keys — PostgreSQL: id UUID PRIMARY KEY DEFAULT gen_random_uuid(). For tables over 100 million rows use v7: time ordering keeps the B-tree index compact and speeds up INSERTs by 2-5x compared to v4.
  • Idempotency keys in REST APIs — Stripe and PayPal require an Idempotency-Key header on POST requests so a retry after timeout does not double-charge. UUIDv4 is the industry default: the client generates a key like 3f29c3e0-b5c1-4f1a-9d4d-7c5b21a4e2f0, the server caches the response under it for 24 hours.
  • S3 and CDN filenames — uploads get a UUID instead of the original name: s3://bucket/uploads/8d3a9e7c-...-da12fb.pdf. Prevents collisions and makes public links unguessable (capability URL pattern). For images often combined with a hash for content addressing.
  • Distributed tracing — OpenTelemetry uses 64-bit span IDs and 128-bit trace IDs (not quite UUID format but same size class). Custom correlation IDs in logs and HTTP headers (X-Request-ID: ...) are typically UUIDv4. Lets you follow a request across 20 microservices.
  • Offline-first apps — Notion, Linear or Figma create IDs on the client so an entity (task, page, frame) is link-targetable before any server sync. v4 or v7 — with v7, creation order is encoded in the key, simplifying sync conflict resolution.

Limits, pitfalls and when UUIDs do not fit

UUIDs are not magic. Three common pitfalls: (1) v4 as primary key on large tables — random insert order destroys B-tree index locality and write-ahead logs. Fix: v7 or ULID. (2) v1 in public systems — the first 60 bits encode a timestamp and parts of the MAC address, creating privacy issues (see the "Cohen UUID" story). (3) v4 for security tokens is fine (122 bits of entropy is enough), but if the UUID library does not use crypto.getRandomValues and falls back to Math.random(), all is lost. Verify before use: does your UUID library provably produce cryptographically secure v4 IDs? Node.js crypto.randomUUID() yes, older polyfills often no.

Frequently asked questions

Should I use UUIDv4 or UUIDv7?
Since RFC 9562 (2024) the default is v7 when the ID ends up as a database key or sort key. v4 is the right choice for tokens, session IDs, idempotency keys or anything where creation time must not leak. v7 contains the timestamp readably in the first 48 bits (~6 hex chars) — fine for order or user IDs, but unwanted for API keys.
Is crypto.randomUUID() safe and fast?
Yes to both. The Web Crypto API is implemented in all modern browsers (Chrome 92+, Firefox 95+, Safari 15.4+, Node.js 19+) and uses the OS CSPRNG. Throughput on commodity hardware reaches millions of UUIDs per second. This generator uses the same API for v4; v7 and v1 draw from the same pool via crypto.getRandomValues.
Can a UUID collide?
In theory yes, in practice ruled out. UUIDv4 (122 random bits) needs about 2.7 * 10^18 UUIDs for a 50% collision probability — at 1 billion UUIDs per second, that takes ~85 years. Realistic collisions only happen with buggy generators (no CSPRNG, broken seed), not from bad luck.
What is the difference between UUID and GUID?
None technically. GUID (Globally Unique Identifier) is Microsoft's name for the same 128-bit structure. Only quirk: Microsoft tools traditionally print GUIDs uppercase and in braces: {8D3A9E7C-1F2B-4A5D-9E0F-DA12FB44A1C2}. You can switch formats via this tool's format option.
Should I store UUIDs as VARCHAR or as a native UUID type?
Native wherever possible. PostgreSQL and SQL Server have a 16-byte UUID type, MySQL 8+ via BINARY(16). VARCHAR(36) costs 36 bytes instead of 16 — 2.25x more storage, 2.25x more I/O, slower index scans. For MySQL UUID_TO_BIN(..., 1) additionally swaps the UUID so the timestamp is at the front (pseudo-v7). With v7 that swap is already native.
Are there shorter alternatives to UUIDs?
Yes, several: ULID (26 Crockford base32 chars, time-sortable, effectively the v7 predecessor), NanoID (21 URL-safe chars, ~126 bits entropy, no hyphens), KSUID (27 chars, 32-bit timestamp + 128-bit random). For URLs NanoID or base62-encoded UUIDs (22 chars) feel cleaner. For maximum DB column, log and standard compatibility, UUIDv7 remains the safest pick.

Related tools