Skip to content
ansezz.

▸ Free tool

UUID Generator.

Random v4 or time-ordered v7 UUIDs from your browser's own CSPRNG, plus an inspector for any UUID. Nothing is sent anywhere.

▸ v4 or v7, your pick

v4 is pure random. v7 starts with a timestamp, so it sorts by time and is kind to database indexes. For real primary keys, still generate them where the row is created.

Version

Shows the first generated UUID until you paste your own.

What a v4 UUID actually is

A UUID is 128 bits, printed as 32 hex digits in an 8-4-4-4-12 grouping. In version 4, six of those bits are not yours: four say "this is version 4" and two mark the variant. The other 122 come straight out of a random source. You can read both fields off the string without a parser: the third group starts with the version digit, always 4 here, and the fourth group starts with the variant digit, always 8, 9, a, or b.

This page calls crypto.randomUUID() and falls back to crypto.getRandomValues() with those six bits set by hand. No Math.random() anywhere, which turns out to be the whole ballgame.

The collision maths, in plain terms

122 random bits is about 5.3 × 10³⁶ values, but the number that matters is the birthday bound, which sits near the square root of that. Concretely: generate 103 trillion v4 UUIDs and your odds of a single duplicate anywhere in the pile are roughly one in a billion. You are not going to collide.

What you can break is the assumption underneath the maths: a real CSPRNG. Duplicates in the wild come from Math.random(), from a PRNG in a process that forked after seeding, from images that boot with an identical entropy pool, and from code that truncates a UUID to fit a legacy column. Keep the unique constraint anyway, not as a retry mechanism, but as documentation of intent.

The version decides your write pattern

The versions are not quality tiers, they are different trade-offs. v1 embeds a timestamp and a node ID that is traditionally the machine's MAC address. It leaks both, and because the timestamp fields sit out of order, it does not even sort by time. v4 is pure randomness. v7, standardised in RFC 9562 in 2024, leads with 48 bits of Unix milliseconds, big-endian, then randomness.

  v1 v4 v7
What the 128 bits hold 60-bit timestamp + 14-bit clock sequence + 48-bit node ID 122 random bits 48-bit millisecond timestamp + up to 74 random bits
Sorts by creation time
Leaks something MAC address and creation time Creation time, by design
Good primary key at scale
Where it is specified RFC 4122, kept in RFC 9562 RFC 4122, kept in RFC 9562 RFC 9562 (2024)
Generated on this page

That ordering is not cosmetic. It is an index problem, and it is the production failure people actually hit. A primary key is a B-tree key. Time-ordered values append to the rightmost leaf page, which stays hot in the buffer pool. Random v4 values target a random page every time: the working set becomes the entire index, pages split down the middle instead of filling up, and the moment the index outgrows RAM your insert throughput falls off a cliff. MySQL with InnoDB suffers worst, because the table is the primary-key B-tree and every secondary index carries a full copy of that key.

This tool generates both. For keys in a table that will get large, use v7 or ULID, and create them where the row is created: uuidv7() is built into PostgreSQL 18 and there is a library for every language. ULID is the same idea (48 bits of milliseconds plus 80 random) in a 26-character base32 encoding that sorts as text; v7 wins on being a real UUID that drops into a uuid column.

Store 16 bytes, not 36 characters

A UUID is 128 bits. The canonical text form is 36 characters, so char(36) spends 36 bytes to hold 16 bytes of information. PostgreSQL has a native uuid type; MySQL does not, so use binary(16) with UUID_TO_BIN() and BIN_TO_UUID() at the edges; SQL Server has uniqueidentifier.

The 20 wasted bytes sound trivial until you remember that InnoDB copies the full primary key into every secondary index. Five indexes, five more copies of the waste, in RAM as well as on disk.

When an auto-increment integer still wins

A bigint is 8 bytes, strictly monotonic, readable in a log, and half the width of a UUID in every index and foreign key. One database, one writer, IDs that never appear in a URL, that is the correct choice, and a UUID there is pure tax.

UUIDs earn their place when you need the ID before the insert (client-side creation, offline-first sync, idempotency keys), when you merge rows from several sources, when you shard, or when the ID is public: /orders/1024 tells a competitor your order count and invites a stranger to try 1025. Most teams land on both: a bigint primary key for joins, plus an indexed UUID column for the outside world.

Questions, answered.

Are UUIDs guaranteed to be unique?

Not guaranteed, just overwhelmingly unlikely to collide. A v4 UUID carries 122 random bits, and the birthday bound puts you at roughly a one-in-a-billion chance of a single duplicate after generating 103 trillion of them. The real risk is never the maths, it is the random source: values drawn from Math.random(), from a PRNG seeded identically across forked workers, or from a library that truncates the UUID to fit a column will collide long before probability says they should.

Are the UUIDs from this generator cryptographically random?

Yes. The page calls crypto.randomUUID(), which the Web Crypto spec requires to be backed by a cryptographically secure random source, and falls back to crypto.getRandomValues() with the version and variant bits set by hand where randomUUID() is not available. Both need a secure context, so HTTPS or localhost. Nothing is generated on a server and nothing is sent anywhere. Load the page once and it keeps working offline.

Does this tool generate UUID v7?

Yes. Pick v7 and the tool builds RFC 9562 version 7 UUIDs: a 48-bit Unix millisecond timestamp first, then random bits. Inside one batch, values made in the same millisecond use a counter so the list is strictly increasing. Use these for test data and fixtures. For real primary keys, generate v7 where the row is created, for example with uuidv7() in PostgreSQL 18 or a library in your language.

How do I get the timestamp out of a UUID?

Paste it into the inspector. For v7 the first 48 bits are Unix milliseconds, so the time reads straight off the front. For v1 and v6 the tool rebuilds the 60-bit count of 100 nanosecond steps since October 15, 1582 and converts it. A v4 UUID has no timestamp at all, it is 122 random bits. The inspector also shows the version and variant, and spots the nil and max UUIDs.

Should I use a UUID as a database primary key?

It depends on the version and the write volume. Random v4 keys scatter inserts across the whole B-tree instead of appending to the rightmost page, which causes page splits, index fragmentation, and a sharp drop in insert throughput once the index stops fitting in memory. It hurts most on MySQL with InnoDB, where the table itself is the primary-key B-tree and every secondary index stores a full copy of that key. If you want a UUID primary key, use a time-ordered one: v7 or ULID.

How should I store a UUID in MySQL or PostgreSQL?

As 16 bytes, never as a 36-character string. PostgreSQL has a native uuid type that stores the raw 128 bits; MySQL has no UUID type, so use binary(16) with UUID_TO_BIN() and BIN_TO_UUID() to convert at the edges. A char(36) column wastes 20 bytes on every row, and in InnoDB that waste is repeated inside every secondary index, on top of slower string comparison under a collation.

Can I use a UUID as an API key or a password reset token?

A v4 UUID from a proper CSPRNG has 122 bits of entropy, so guessing one is not the problem. The format is. UUIDs get logged, pasted into URLs, and leaked through Referer headers, and nothing about the shape of a UUID tells the next developer that this particular one is a secret. Generate a purpose-made random token instead, keep it out of URLs, and store only its hash.

Keep going

▸ Last verified:

Need this in production?

Building a Laravel SaaS? I design and ship multi-tenant Laravel apps, from first commit to production.

Laravel SaaS MVP

Keep reading