Utilify

UUID v7 Generator (Time-Ordered) & Decoder

Generate time-ordered UUID v7 identifiers and decode their embedded timestamp. Free, fast, runs entirely in your browser.

Built and maintained by Jay SooUpdated September 9, 2026

How to use UUID v7 Generator

  1. 1
    Choose how many

    Set how many UUID v7 values to generate (1–100).

  2. 2
    Generate

    Click Generate. Each value is created locally with cryptographic randomness.

  3. 3
    Copy

    Copy a single UUID or use Copy all to grab the whole batch.

  4. 4
    Decode (optional)

    Paste any v7 UUID into the decoder to read its embedded creation time.

About UUID v7 Generator

UUID version 7 is the newest standard UUID, defined in RFC 9562 (2024), and it solves the biggest practical problem with the classic random UUID v4: ordering. A v4 UUID is 122 bits of pure randomness, so consecutive values land in unrelated positions. Used as database primary keys, every insert scatters across the B-tree index, which fragments pages, hurts cache locality, and slows writes at scale.

UUID v7 addresses this by putting a 48-bit Unix millisecond timestamp at the front of the identifier, followed by the version digit, then 74 further bits — 12 called rand_a and 62 called rand_b, with the 2-bit variant marker every UUID carries sitting between them. Because the timestamp leads, v7 values sort into creation order across milliseconds, so new rows append near the end of the index instead of scattering — the insert behaviour of an auto-incrementing integer with the decentralisation and unguessability of a UUID, and no central allocator.

What goes in those 74 bits is where implementations differ, and it decides whether a batch generated inside a single millisecond stays ordered. RFC 9562 §6.2 is explicit that it should: "if one thousand UUIDs are generated for the same timestamp, there should be sufficient logic for organizing the creation order of those one thousand UUIDs." Fill the bits with pure randomness and that logic is missing — which is what this generator used to do. Measuring its old output, a default batch of 5 already came out with one of its four adjacent pairs inverted, and at 100 values 49 of 99 adjacent pairs were out of order — a coin flip, which is exactly what a random tiebreak predicts. It now implements the RFC's method 1 instead, spending the 12 bits immediately after the version digit on a counter that is randomly seeded on each new millisecond and incremented for every value within it, leaving 62 cryptographically random bits. Re-measured, batches of 5, 100, 1,000, and 20,000 came out with zero inversions, and the line under the output verifies that ordering for the batch you generated.

The counter costs entropy, and it is worth knowing how much: 62 random bits still means about 2.53 billion values before a 50% chance of any collision, and that only applies to values sharing both a millisecond and a counter position. The timestamp is the more meaningful trade-off — it is readable by anyone, to the millisecond, which is a genuine information leak if creation times are sensitive. The 48-bit field itself is not a concern: it runs until the year 10889.

A v7 UUID looks identical in shape to any other UUID — 32 hex digits in the 8-4-4-4-12 layout, with the version digit fixed to 7 — so anything that accepts a UUID accepts these. Generation and decoding both run entirely in your browser through the Web Crypto API, so no value is ever sent to a server. If you want good write behaviour on a UUID primary key, v7 is usually a better default than v4; if you need identifiers that carry no time signal at all, stay with v4.

The three ways RFC 9562 keeps a same-millisecond batch ordered

The 48-bit timestamp orders values across milliseconds. Inside one millisecond the timestamp is identical, so ordering falls to whatever comes next — and §6.2 of the spec sets out three ways to make those bits carry the sequence. Choosing between them is the main design decision in a v7 generator:

Method (RFC 9562 §6.2)How it orders same-tick valuesBits it spendsCeiling per millisecondWhy we did or did not pick it
Method 1 — fixed bit-length dedicated counterCounter bits sit immediately after the timestamp and are randomly initialised on each new tick12 bits of rand_a (the spec allows extending into rand_b)4,096 positions; seeded within the first 1,024 here, so at least 3,072 remainWhat this tool uses — the ordering lives in one small, fixed field, so it can be read straight out of a UUID and checked. The spec's guidance is that "the counter SHOULD be at least 12 bits but no longer than 42 bits"
Method 2 — monotonic randomThe random field doubles as a counter, "incremented in the least significant position for each UUID created on a given timestamp tick"The whole random fieldEffectively unboundedRetains more entropy and needs no finer clock either, but the ordering guarantee is then spread across all 74 bits, so it cannot be verified by reading one field
Method 3 — replace leftmost random bits with increased clock precisionSubstitutes finer clock readings for up to 12 bits after the timestampUp to 12 bitsWhatever the real clock resolution allowsUnavailable in a browser: Date.now() advanced in 1 ms steps in all three engines we measured, and performance.now() only resolved finer in Chrome 153 (0.1 ms) — still 1 ms in Firefox 155 and WebKit 26.6

The spec also requires that "Counter rollovers MUST be handled by the application to avoid sorting issues." This generator waits for the clock to advance rather than wrapping the counter, and holds the timestamp still if the system clock steps backwards, so a sequence never regresses. For the database-side consequences of getting this wrong, our UUID v4 vs v7 benchmark post measured counter-less v7 at 50.1% of adjacent pairs ordered in a burst, alongside index-locality numbers.

When to use UUID v7 Generator

  • Database primary keys

    Keep index inserts sequential and fast while staying globally unique, no central allocator needed.

  • Distributed systems

    Generate unique IDs on many nodes at once without coordination or collisions.

  • Sortable event IDs

    Tag log records or events with v7 IDs so they sort into creation order by default.

  • Quick auditing

    Decode a v7 to see roughly when a record was created without a separate timestamp column.

Four v7 traps, starting with the one we shipped

  • Assuming the millisecond timestamp is enough to order a batch

    This generator previously filled everything after the timestamp with randomness, which reads as correct until you measure it. A default batch of 5 came out with one of its four adjacent pairs inverted; at 100 values, 49 of 99 adjacent pairs were out of order — a coin flip, which is what a random tiebreak predicts. Across all 4,950 possible pairs that run measured 1,231 inversions, or 24.9%, and that figure is lower than the adjacent one for a reason worth knowing: the batch spanned two milliseconds, and pairs drawn from different milliseconds always sort correctly. Same-millisecond pairs are the ones that land at roughly 50%, so the whole-batch percentage moves around with how many milliseconds a batch happens to cover. RFC 9562 §6.2 is direct about the requirement: "if one thousand UUIDs are generated for the same timestamp, there should be sufficient logic for organizing the creation order of those one thousand UUIDs." With the counter in place, batches of 5, 100, 1,000, and 20,000 measured zero inversions.

  • Trusting that a v7 library is monotonic without checking

    The counter schemes are methods the spec describes, not behaviour every implementation ships, and a generator without one looks completely normal — correct version digit, correct variant, decodable timestamp. It takes three lines to find out, and it is worth running against whatever library you actually deploy rather than assuming.

    const ids = Array.from({ length: 100 }, () => yourV7());
    const sorted = [...ids].sort();
    console.log(ids.every((v, i) => v === sorted[i]));  // false → not monotonic
  • Applying MySQL's time-part swap to a v7

    UUID_TO_BIN(uuid, 1) is standard advice for storing UUIDs in an indexed column, and it is wrong for v7. The MySQL manual describes the flag as swapping "the time-low and time-high parts" so that it "moves the more rapidly varying part to the right", and states plainly that "time-part swapping assumes the use of UUID version 1 values". A v7 already leads with its timestamp, so the swap drags the version and counter bits to the front and the timestamp into the middle. We generated six v7 values across distinct milliseconds: stored unswapped they sorted in creation order, while sorting their swapped forms returned creation positions 3, 2, 1, 6, 4, 5. Store v7 with no swap flag.

    -- v1: helps.  v7: destroys the ordering you chose v7 for.
    UUID_TO_BIN(id, 1)
    -- v7: use this
    UUID_TO_BIN(id)
  • Forgetting that a counter leaks a rate signal too

    The millisecond timestamp being public is the well-known v7 trade-off. A dedicated counter adds a smaller one: two values from the same generator in the same millisecond differ by exactly the number of IDs it produced in between, so the gap is readable. Seeding the counter randomly on each tick — which the spec calls for, and which this tool does — hides the absolute count but not that difference. If neither the creation time nor the generation rate should be observable, v4 is the right choice.

Frequently asked questions

What is the difference between UUID v4 and v7?+

Both are 128-bit UUIDs, but v4 is fully random while v7 begins with a 48-bit timestamp. That makes v7 time-ordered and far friendlier to database indexes, whereas v4 carries no time information.

Are the values from this tool ordered within the same millisecond?+

Yes. The 12 bits after the version digit hold a counter that is randomly seeded on each new millisecond and incremented for every value generated inside it — method 1 of RFC 9562 §6.2. Batches of 5, 100, 1,000, and 20,000 measured zero inversions against generation order, and the line beneath the output re-checks it for the batch on screen. This matters because a millisecond timestamp on its own does not order a batch: the previous version of this generator put 49 of 99 adjacent pairs out of order at 100 values.

Are UUID v7 values safe to use as primary keys?+

Yes, and they are often better than v4 because the time-ordered prefix keeps B-tree index inserts sequential, reducing fragmentation and improving write throughput at scale. On MySQL, store them with UUID_TO_BIN(id) and not UUID_TO_BIN(id, 1) — the swap flag is designed for v1 and scrambles a v7 timestamp prefix.

Can someone read the creation time from a v7 UUID?+

Yes. The first 48 bits are a Unix millisecond timestamp, so anyone can decode roughly when the ID was generated. If a time signal is undesirable, use v4 instead.

Is the generation cryptographically secure?+

The 62 bits of rand_b come from your browser crypto.getRandomValues, a cryptographically secure source — enough for roughly 2.53 billion values before a 50% chance of any collision, and that only applies to values sharing both a millisecond and a counter position. The timestamp and the counter are, by design, predictable.

When does the 48-bit timestamp run out?+

Not soon enough to plan around: 2^48 − 1 milliseconds after the Unix epoch falls in August of the year 10889 — about 8,920 years measured from the epoch itself. The practical limits on v7 are the timestamp leak and same-millisecond ordering, not the field width.

Does anything get sent to a server?+

No. Generation and decoding both run entirely in your browser; no UUID ever leaves your device.

Related tools

From the blog