UUID Generator
Generate UUIDs v1, v4, or v7 for IDs, primary keys, or distributed systems.
Version 1: Timestamp-based, includes MAC address information
Version 4: Randomly generated, most commonly used
Version 7: Timestamp-based with random data, sortable by creation time
Produce v1, v4, or v7 identifiers and copy them straight into a schema, a fixture, or a request. The version you pick decides three separate things: how likely a collision is, what metadata travels with every ID you hand out, and how your primary-key index behaves under insert load. Those consequences are what this page covers.
v4 gives you 122 random bits, not 128
A UUID is 128 bits wide, but v4 spends four of them on the version nibble and two on the variant marker, leaving 122 bits of actual randomness. Apply the birthday bound to that space and you need roughly 2.71 × 1018 values before there is a 50% chance of a single collision — at a billion generated every second, about 86 years of continuous output.
The arithmetic is not where v4 goes wrong; the entropy source is. Math.random() is not a cryptographic generator. V8 implements it with xorshift128+, whose internal state can be recovered from a short run of outputs, so a v4 built on it is predictable to anyone who has seen a handful. Use crypto.randomUUID() (available in Node and in browsers, though browsers require a secure context), crypto.getRandomValues() if you are assembling the bytes yourself, or SecureRandom on the JVM.
One consequence is worth stating plainly: 122 random bits is enough entropy for an unguessable capability URL or a password-reset token, so a v4 can double as a bearer secret. A v1, v6 or v7 cannot. Most of their bits are a timestamp, and anyone holding one identifier can enumerate a narrow window around it. Do not change versions on a table whose IDs are quietly acting as access control.
What a v1 tells the person who receives it
A v1 packs a 60-bit timestamp counting 100-nanosecond intervals since 15 October 1582 — the date the Gregorian calendar took effect — plus a 14-bit clock sequence and a 48-bit node identifier that RFC 4122 specified as the machine's IEEE 802 MAC address. Every v1 you emit therefore discloses which network interface produced it and when, to a resolution of one ten-millionth of a second.
That is a real disclosure rather than a theoretical one. In 1999, investigators tracing the Melissa macro virus made use of identifiers embedded in Word documents, which at the time carried the author's network-card address. If your public API hands out v1 primary keys, you are publishing host hardware addresses and precise record creation times to every client that calls it.
The clock sequence exists to survive a clock that runs backwards, but it does not help when two hosts share a node ID. Cloned VM images and containers on a shared virtual bridge can present the same MAC, which turns "unique without coordination" into a coin flip. RFC 9562 now permits a random node ID instead, and defines v6 as v1 with the timestamp fields reordered into big-endian order so values sort chronologically — a migration path if you already have v1 data you cannot reformat.
Random primary keys and B-tree page splits
A v7 places a 48-bit big-endian count of milliseconds since the Unix epoch in its leading bits, so v7 values generated in time order also sort in byte order and in string order. That single property is the entire reason the version exists.
Consider what a random key does to a B-tree. PostgreSQL indexes are built from 8 KB pages and InnoDB from 16 KB pages. Sequential inserts all land in the right-most leaf, which stays resident in memory and fills to capacity before a new page is allocated. Random inserts land somewhere different every time; once the index no longer fits in RAM, each insert becomes a random read followed by a random write, and pages split down the middle rather than at the end, so they settle near half full. The index ends up materially larger and the write path materially slower for exactly the same rows.
Under InnoDB the effect compounds, because the table is clustered on the primary key — a random PK randomises the physical row order as well, and every secondary index stores a copy of the PK as its row pointer. SQL Server ships NEWSEQUENTIALID() to dodge the same problem.
Time ordering is not free, though. A v7 discloses its creation time to the millisecond, and two of them are enough to estimate your creation rate. In range-partitioned stores such as HBase or Bigtable, monotonically increasing keys hot-spot every write onto a single region — those systems explicitly recommend the random keys that relational engines dislike.
128 bits stored as 36 characters
The canonical text form is 36 characters — 32 hex digits plus four hyphens in 8-4-4-4-12 groups — representing 16 bytes of value. Storing the text form more than doubles the size of the key, and in an index that difference is charged against every single entry.
PostgreSQL has a native uuid type that occupies 16 bytes and compares as an integer, and gen_random_uuid() has been in core since version 13. MySQL has no UUID column type at all; the equivalent is BINARY(16) with UUID_TO_BIN() and BIN_TO_UUID(), whose optional swap flag rearranges a v1's time fields so the stored bytes sort chronologically.
The cost of getting this wrong in MySQL is easy to quantify. InnoDB secondary indexes store the primary key as the row pointer, so a CHAR(36) PK adds 20 bytes to every entry of every secondary index on the table. On a utf8mb4 column, an index over VARCHAR(36) reserves four bytes per character and counts 144 bytes against InnoDB's 3072-byte index key limit instead of 16.
Whichever form you choose, normalise it. RFC 9562 requires generators to emit lowercase hex while requiring parsers to accept either case, so a text column will happily hold 550E8400-E29B-41D4-A716-446655440000 and its lowercase twin as two unrelated rows unless you enforce one form on the way in.
Versions and byte orders you meet in other systems
RFC 9562, published in May 2024, replaced RFC 4122 as the normative specification. It kept v1 through v5, added v6, v7 and v8, and defined a Max UUID of all one bits (ffffffff-ffff-ffff-ffff-ffffffffffff) alongside the long-standing Nil UUID of all zeros. Both are legal values, and both are usually a bug in disguise — a Nil UUID sitting in a foreign key almost always means an uninitialised variable rather than a deliberate sentinel.
v3 and v5 are deterministic rather than random: hash a namespace UUID together with a name, MD5 for v3 and SHA-1 for v5, and the same inputs always produce the same output. That is the right tool for an idempotent identifier derived from a natural key, and v5 is the one to reach for. Neither is a security primitive, since the input is recoverable by guessing. v8 is a deliberately unspecified slot for custom layouts, constrained only by the version and variant bits.
Byte order is where cross-platform data goes wrong. Microsoft's GUID struct stores its first three fields in native little-endian order, so the same 16 bytes render as two different strings depending on whether you read them as an RFC 9562 UUID or as a Windows GUID. A value taken from Guid.ToByteArray() and formatted as a UUID comes out scrambled. SQL Server adds another layer: its uniqueidentifier type compares the last six bytes first, so ORDER BY on that column matches neither string order nor v7 order.
When you validate, check the semantics rather than the shape. A pattern that only tests for 32 hex digits and four hyphens will accept values that are not valid UUIDs of any version. Counting from one, the 15th character of the canonical string is the version digit — the 4 in 550e8400-e29b-41d4-a716-446655440000 — and the 20th must be 8, 9, a or b for the RFC variant — worth confirming in the regex tester before you ship the pattern.
Related tools
Try these tools that work well with this one
Cron Expression Generator
Convert natural language schedules to cron expressions
Lorem Ipsum Generator
Generate placeholder text for design mockups
Password Generator
Generate secure passwords with customizable options
QR Code Generator
Generate customizable QR codes
API Tester
Send HTTP requests and view responses
Base64 Decoder
Convert Base64 back to original text and files
Related guides
Tutorials and guides to get more from this tool
UUIDs Explained: v1, v4, v7 and When to Use Them
UUID v4 vs v7: Which one should you use? Complete breakdown of all versions with real-world examples. Choose the right UUID in 2025.
Regex Cheat Sheet: Patterns That Hold Up in Production
A practical regex reference with tested patterns for IDs, dates, URLs and logs, plus the mistakes that cause bugs and catastrophic backtracking.
JavaScript .then() and .catch(): Promise Error Handling Explained
How .then().catch() chains work in JavaScript: return values, error propagation, finally, common mistakes, and when to use async/await instead.
ThenCatch is a free developer toolkit. Learn more about us.