UUID / GUID Generator

A version 4 UUID is 122 bits of randomness formatted into the familiar 8-4-4-4-12 hex layout. It is the default choice for identifiers that must be unique without coordinating with a central authority, and a surprisingly bad choice as a database primary key. Both points are worth understanding before you commit to one.

How to use it

  1. Set how many UUIDs you need.
  2. Each one is generated from crypto.getRandomValues, the browser cryptographically secure random source.
  3. Copy the results. Nothing is transmitted or logged.

What the 128 bits are actually doing

A UUID is 128 bits, but a v4 UUID is not 128 bits of randomness. Four bits encode the version, fixing the first character of the third group to 4, and two more encode the variant, restricting the first character of the fourth group to 8, 9, a, or b. That leaves 122 random bits.

Those bits come from crypto.getRandomValues here, which draws from the operating system cryptographically secure random number generator. This matters more than it sounds. Implementations built on Math.random are seeded predictably and produce UUIDs an attacker can guess, which turns any identifier used as a capability, such as a password reset token or an unlisted share link, into an open door.

Collision probability, concretely

The usual claim is that v4 UUIDs never collide. The accurate version is that collisions are possible and overwhelmingly unlikely, and the numbers are worth having.

By the birthday bound, reaching a 50 percent chance of a single collision requires roughly 2.7 quintillion UUIDs, which is 2.7 times 10 to the eighteenth. Generating a billion UUIDs per second, that takes about 85 years. For a more practical scale: after generating 100 trillion UUIDs, the probability of any collision is still around one in 100 million.

The realistic failure mode is not the birthday bound, it is a broken random source. A misconfigured container image with a starved entropy pool, or a library quietly falling back to Math.random, will produce duplicates long before mathematics does.

Why v4 makes a poor primary key

Random UUIDs are hostile to B-tree indexes. Because each new value lands at an unpredictable point in the index, inserts touch pages scattered across the whole structure rather than appending to the end. On a table larger than available memory that means a random disk read per insert, page splits throughout the tree, and index fragmentation that grows steadily worse.

Sequential integers have the opposite behaviour: every insert lands on the same hot page. The performance gap on large tables is routinely an order of magnitude.

UUID version 7, standardised in RFC 9562, fixes this by putting a millisecond timestamp in the high bits and randomness in the low bits. Values sort roughly in creation order, so inserts stay clustered, while remaining unique without coordination. If you are choosing an identifier scheme for a new table today, v7 is usually the better answer, with v4 reserved for cases where the identifier must leak nothing about when it was created.

Storage format matters too

A UUID stored as a 36-character string in a VARCHAR column takes 36 bytes plus overhead, against 16 bytes for a native binary type. On a table with several UUID columns and a hundred million rows, that difference is measured in gigabytes, and it propagates into every index that references the column.

PostgreSQL has a native uuid type. MySQL does not, but BINARY(16) with UUID_TO_BIN works, and its swap-flag argument reorders the timestamp fields of a v1 UUID to improve index locality.

At a glance

Versionv4, RFC 4122 / RFC 9562
Random sourcecrypto.getRandomValues
Random bits122 of 128
TransmittedNothing, generation is local

Frequently asked questions

Are these UUIDs safe to use as security tokens?

They are generated from a cryptographically secure source, so 122 bits of unpredictability is ample. The caveat is lifecycle rather than entropy: a token also needs expiry and revocation, which the identifier itself cannot provide.

Can two v4 UUIDs ever be the same?

In principle yes, in practice no. Reaching a 50 percent chance of one collision takes around 2.7 quintillion UUIDs. A broken random source is a far more realistic cause of duplicates than the birthday bound.

Should I use UUIDs as database primary keys?

Not v4, on large tables. Random values scatter B-tree inserts and fragment the index. UUID v7 keeps the coordination-free property while sorting by creation time, which preserves index locality.

What is the difference between a UUID and a GUID?

Nothing meaningful. GUID is the Microsoft name for the same 128-bit structure. Microsoft tooling sometimes displays them in braces and, for some legacy formats, byte-swaps the first three fields.

Read more

Tokens, hashes, and identifiers — Why a UUID is not a secret, a hash is not encryption, and a JWT you have not verified is just a base64 string.

Related tools