utilime

Small tools that finish the job.

Generate UUIDs

Pick a version and how many you want. Version 7 carries the time in its leading bits, so the identifiers sort into the order they were created and behave properly as database keys.

Drop a file hereor click to choose · it stays on your device

How it works

A UUID is 128 bits, written as 32 hexadecimal characters in five hyphenated groups. The point of the format is that anybody can mint one without asking a central authority for permission, and still expect nobody else to produce the same value. That is what makes it useful for database keys, file names, log correlation, and the idempotency key on an API request. Six of the 128 bits are spoken for by the specification, leaving between 62 and 122 to carry the actual distinctness, depending on the version you ask for.

What the 128 bits are doing

Six bits are structural. Four are the version, at the start of the third group: a version 4 UUID has a 4 there and a version 7 UUID has a 7. Two more are the variant, at the start of the fourth group, and RFC 9562 fixes them to binary 10. Those two bits are the high end of a hex character whose other two bits are free, so that character can only ever be 8, 9, a or b. Anything else there was not produced to the standard, and reading one character is the cheapest validity check available.

Version 4 spends every remaining bit on chance

122 random bits and no structure whatsoever. Uniqueness becomes a probability rather than a guarantee, and the probability is generous: reaching a one-in-a-billion chance of a single duplicate takes roughly 103 trillion of them. The arithmetic is the birthday bound, counting pairs rather than values, so the risk climbs with the square of how many you have made. At any volume a real system reaches, a weak random source is a far likelier cause of a repeat than the size of the space.

Why a random key is slow in a database

Most indexes are B-trees, held in sorted order on disk in fixed-size pages. Inserting a row means finding the page its key belongs on and writing there. Sequential keys keep landing on the same page, which stays in memory and absorbs thousands of inserts between flushes. Random keys land somewhere different every time, so once the table outgrows memory almost every insert has to read a page in first. Those pages also split at around half full instead of packing tight, so the index grows larger and fewer rows fit in cache.

Version 7 puts the clock in front

RFC 9562 arrived in May 2024 and replaced RFC 4122. Its version 7 layout opens with a 48-bit count of milliseconds since 1970, then the version, then 12 more bits, then the variant, then 62 random bits. Because the timestamp sits at the most significant end, and hexadecimal sorts in the same order as the numbers it spells, sorting version 7 UUIDs as text sorts them by the moment they were made. Inserts return to the end of the index, and the 62-bit tail keeps two from the same millisecond apart.

Forty-eight bits of milliseconds runs out in the year 10889, so version 7 has no rollover to plan around. What the layout costs is privacy: the creation time is legible to anyone holding the identifier, down to the millisecond. Sorting requires a readable timestamp, so those two properties cannot both be had, and choosing between them is the real decision this page asks you to make.

Two of them inside one millisecond

A millisecond is a long time. A loop asking for a thousand UUIDs gets them all inside one, and if the bits after the timestamp were purely random the batch would come back scrambled, losing the single property version 7 exists to provide. So the 12 bits between the version and the variant hold a counter here: seeded randomly in the lower half of its range at the start of each new millisecond, incremented for every UUID after that, with 2048 increments of headroom. If it ever runs dry, the timestamp borrows the next millisecond.

What version 1 got wrong

Version 1 is also time-based, counting 100-nanosecond intervals since 15 October 1582, the day the Gregorian calendar came into use. Two decisions spoiled it. Its timestamp is split across three fields with the least significant part first, so sorting version 1 values tracks time only until that leading field wraps, which happens every 429 seconds. Ordering restarts on that seven-minute cycle, and so does the index locality. The trailing 48 bits were meant to hold the machine's MAC address, putting a hardware serial number inside every identifier. The author of the 1999 Melissa virus was traced that way, through GUIDs left in a Word document.

The node here is random rather than a real address, with the multicast bit set as the specification requires so that it cannot be confused with hardware. It is drawn once per batch and shared, because a node identifies a machine and not an identifier. Version 6 is version 1 with the timestamp fields reordered so that they sort, and it exists for systems already holding version 1 data. New work has no reason to prefer it to version 7.

Where the random bits come from

crypto.getRandomValues, the platform's cryptographic generator. Math.random is the wrong instrument, and the reason has nothing to do with speed. Its specification declines to require unpredictability at all, V8 implements it as xorshift128+, and that generator's internal state can be recovered from a short run of observed output, after which every value it will produce next is known and the ones before it can be replayed. An identifier somebody can predict is an access-control failure in any system that treats a URL holding one as private.

Nil and Max

Two UUIDs are defined as literals. Nil is 128 zero bits, Max is 128 one bits, and neither carries a version or a variant, so they are the two values that fail the one-character check described above. Nil is the conventional stand-in for absent, and Max is useful as the upper bound of a range query over an indexed UUID column. Both are worth knowing precisely because they are the exceptions: code that validates the variant character has to let these two through deliberately.

Questions

Which version should I pick?

Version 7 for anything that becomes a database key, because it sorts by creation time and keeps inserts at the hot end of the index. Version 4 wherever the creation time should stay private, and for anything token-shaped, because it carries no structure to read. Version 1 only to match data you already hold. If nobody has told you which, version 4 is what most systems mean by a UUID and version 7 is the better key.

Does a version 7 UUID reveal when the record was created?

Yes, to the millisecond, to anyone who can see it. That is the trade the layout makes. For an order reference in a URL it is usually harmless and sometimes useful. For a password reset link, an invitation code, or anything where the timing or the rate of your records is sensitive, use version 4 instead: its 122 bits carry no time at all.

Can two of these ever come out the same?

Not inside one batch here. Every version 7 and version 1 UUID on this page takes its own timestamp and counter, so distinctness within a batch is a matter of construction rather than luck, and the page reports that instead of a probability. Across separate batches and separate machines, version 4 rests on 122 random bits and version 7 on the millisecond plus 62. A repeat at that scale would mean the random source had failed.

Why not use crypto.randomUUID?

Because it produces version 4 and nothing else, and no browser API produces version 7. The layout here is assembled by hand for every version from crypto.getRandomValues, which is the same source the built-in function draws on. The random bytes are identical in kind. The difference is that the version and variant bits are placed by this page, which is also how the format choices and the counter come to apply to every version alike.

Which format should I copy?

Lowercase hyphenated is what RFC 9562 tells generators to emit and what every parser accepts, so it is the default. Uppercase is the Microsoft and .NET convention. Braces are the Windows registry and COM form. The compact 32-character form drops the hyphens, which carry no information and cost four characters in a URL. urn:uuid: is the registered URN namespace, for XML and RDF. The quoted list is for pasting straight into an array literal.