TTKTheTextKit

How to Generate a UUID v7: Code, Database and Online Options

How to generate a UUID v7 in JavaScript, Python, .NET and PostgreSQL, why same-millisecond IDs need a counter, and a free generator that keeps them in order.

By TheTextKit TeamPublished

How to generate a UUID v7: the built-in call in Python 3.14, .NET 9 and PostgreSQL 18, and a function for JavaScript

Four cards show how to generate a UUID v7: uuid.uuid7() in Python 3.14, Guid.CreateVersion7() in .NET 9, uuidv7() in PostgreSQL 18, and a short function or library in JavaScript.

To generate a UUID v7, use the built-in call if your platform has one: uuid.uuid7() in Python 3.14, Guid.CreateVersion7() in .NET 9 and later, or uuidv7() in PostgreSQL 18. JavaScript has no built-in, so use a short function, a library or an online generator. A v7 puts a millisecond timestamp first, so new IDs sort by creation time. This guide shows how to generate a UUID v7 in each place, the one mistake that breaks the ordering, and how to check what you made.

How to generate a UUID v7: your options

WhereHowNotes
Python 3.14uuid.uuid7()Built in
.NET 9 or laterGuid.CreateVersion7()Built in
PostgreSQL 18uuidv7()Built in
JavaScriptA 16-line function or a librarycrypto.randomUUID() makes a v4, not a v7
No codeAn online generatorOur tool runs in your browser
Where to generate a UUID v7: Python 3.14, .NET 9, PostgreSQL 18, JavaScript and an online generator

A table of five places and how to generate a UUID v7 in each: Python 3.14 uses uuid.uuid7(), .NET 9 uses Guid.CreateVersion7(), PostgreSQL 18 uses uuidv7(), JavaScript needs a function or library, and an online generator needs no code.

Three platforms have a built-in call. JavaScript does not.

Which one to pick depends on where the ID is created. If the database creates it and you use PostgreSQL 18, call uuidv7() as the column default. If your application creates IDs before saving them, as offline clients and queues do, use the built-in call in your language or a counter-based library. For test data and one-off batches, the online generator is the quickest route. Whichever you pick, the time inside the ID comes from the clock of the machine that made it, so a machine with a wrong clock produces IDs with a wrong time.

What a UUID v7 contains

RFC 9562 defines the layout in section 5.7. A UUID v7 is 128 bits: a 48-bit Unix timestamp in milliseconds, a 4-bit version, 12 bits of pseudorandom data, a 2-bit variant and 62 more pseudorandom bits. Because the timestamp comes first, the first 12 hex digits are the time.

The five fields of a UUID v7: 48-bit timestamp, 4-bit version, 12 random or counter bits, 2-bit variant, 62 random bits

A row of five fields that add up to 128 bits: a 48-bit Unix timestamp in milliseconds, a 4-bit version, 12 bits of random or counter data, a 2-bit variant and 62 random bits.

48 + 4 + 12 + 2 + 62 = 128 bits.

You can decode one by hand. Take the ID 018bcfe5-6800-7555-8f85-5cd01f4d5982. Remove the hyphens and keep the first 12 hex digits, 018bcfe56800. In decimal that is 1700000000000, or 14 November 2023 at 22:13:20 UTC. The Number Base Converter does the hex step. A 48-bit timestamp lasts until the year 10889.

Decoding a UUID v7 by hand: the first 12 hex digits become 1700000000000 milliseconds, which is 14 November 2023 22:13:20 UTC

Three steps for the ID 018bcfe5-6800-7555-8f85-5cd01f4d5982. The first 12 hex digits are 018bcfe56800. In decimal that is 1700000000000. As a date it is 2023-11-14 22:13:20 UTC.

Hex to decimal to date.

How to generate a UUID v7 in JavaScript

Browsers and Node give you crypto.randomUUID(), but it returns a version 4 UUID. We checked, and the version digit was 4. For a v7, fill 16 random bytes, write the timestamp into the first 6 and set the version and variant bits:

function uuidv7() {
  const bytes = crypto.getRandomValues(new Uint8Array(16))
  const ms = Date.now()
  bytes[0] = (ms / 2 ** 40) & 0xff
  bytes[1] = (ms / 2 ** 32) & 0xff
  bytes[2] = (ms >>> 24) & 0xff
  bytes[3] = (ms >>> 16) & 0xff
  bytes[4] = (ms >>> 8) & 0xff
  bytes[5] = ms & 0xff
  bytes[6] = (bytes[6] & 0x0f) | 0x70
  bytes[8] = (bytes[8] & 0x3f) | 0x80
  const hex = [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("")
  return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`
}

We ran it 5,000 times. Every ID matched the pattern for a version 7 UUID, and a decoder read the timestamp as the moment the function was called. It is correct, and it has one weakness that the next section explains.

Generate a UUID v7 in Python, .NET and PostgreSQL

Python. The uuid module added uuid.uuid7() in version 3.14. Its docs say it follows RFC 9562 and uses a 42-bit counter to guarantee monotonicity within a millisecond. We ran it on Python 3.14: the result had version 7.

.NET. Microsoft's documentation for Guid.CreateVersion7 lists .NET 9 and later. It takes the time from UtcNow, and an overload accepts a DateTimeOffset so you can choose the timestamp. The docs say the random sub-fields are seeded with random data.

PostgreSQL. The PostgreSQL 18 documentation lists uuidv7(), which generates a time-ordered version 7 UUID. An optional interval argument shifts the timestamp, which is handy for tests and backfills.

The same-millisecond problem

The timestamp only has millisecond resolution, and a program can make thousands of IDs in a millisecond. Those IDs share a timestamp, so their order depends on the other bits. In the simple JavaScript function above those bits are random, so IDs from the same millisecond sort in random order.

We measured it. The function made 5,000 IDs back to back in 97 distinct milliseconds, and 2,468 of them sorted before the ID generated just ahead of them. RFC 9562 says to take care that UUIDs generated in batches are also monotonic, and it describes putting a fixed-length counter immediately after the timestamp. It also says counter rollover must be handled, for example by moving the timestamp ahead and resetting the counter.

Here is what the three generators did when we tested the order:

GeneratorIDs madeOut of order
Simple JavaScript function5,0002,468
Python 3.14 uuid.uuid7()10,0000
Our generator, one millisecond5,0000

In the last test every ID was unique. A 12-bit counter has only 4,096 values, so 5,000 IDs cannot fit in one millisecond, and in our run the last ID's timestamp was one millisecond after the first. That is the rollover rule at work: the counter passed 4,095 and the clock moved ahead.

UUID v7 ordering test: the simple JavaScript function had 2468 of 5000 out of order, Python 3.14 and our generator had none

A table of three generators and how many IDs were out of order. The simple JavaScript function made 5,000 IDs with 2,468 out of order. Python 3.14 uuid7 made 10,000 with none out of order. Our generator made 5,000 in one millisecond with none out of order.

A counter keeps same-millisecond IDs in order.

Generate and check a UUID v7 online

The UUID v7 Generator makes IDs in your browser with the browser's cryptographic random source, and nothing is sent anywhere. It uses the counter method. Each new millisecond starts the counter at a random value below 2,048, and each further ID adds one. If the counter passes 4,095, the clock moves forward one millisecond. A batch is always ascending.

It also decodes. Paste any UUID, in any of the usual forms, and it names the version and variant and, for a v7, shows the timestamp as a UTC date. IDs from different machines are ordered to the millisecond only, so two made in the same millisecond elsewhere have no guaranteed order. For a plain random ID, the UUID Generator makes v4.

Test your UUID v7 generator in a minute

Whatever you use, run the check we ran. Make a few thousand IDs in a loop and count how many sort before the ID made just ahead of them. The target is zero:

const ids = Array.from({ length: 5000 }, () => uuidv7())
const outOfOrder = ids.filter((id, i) => i > 0 && id < ids[i - 1]).length
console.log(outOfOrder)

Run it on the function you plan to use, not on a sample. A built-in call may guarantee order or may not, and the documentation for .NET and PostgreSQL describes random data in the fields after the timestamp without promising order inside one millisecond. If strict ordering inside a single process matters to you, test it. If it only matters to the millisecond, any of these options is fine.

A second check is the version digit. In a UUID v7 the first character of the third group is always 7, and the first character of the fourth group is 8, 9, a or b. Our 5,000 test IDs all passed that pattern.

Mistakes to avoid when you generate a UUID v7

  • Using the v4 call. crypto.randomUUID() and uuid4() give version 4. Check the first digit of the third group: it should be 7.
  • Trusting random bits for order. A simple function does not keep same-millisecond IDs in order. Use a counter or a built-in that has one.
  • Using seconds. The timestamp is in milliseconds, so seconds produce a date in January 1970.
  • Forgetting the timestamp is public. Anyone holding a v7 can read when it was made. Our guide to UUID v4 vs v7 covers when that matters.
  • Storing it as text. Use the native UUID type if your database has one.

Frequently asked questions

How do I generate a UUID v7?

Use the built-in call if you have one: uuid.uuid7() in Python 3.14, Guid.CreateVersion7() in .NET 9 or later, or uuidv7() in PostgreSQL 18. JavaScript has no built-in, so use a short function, a library or an online generator.

Does crypto.randomUUID() make a UUID v7?

No. In JavaScript it makes a version 4 UUID, which is fully random. We checked the version digit and it was 4. For a v7 you need your own function or a library.

Are UUID v7 values sorted in the order they were made?

Only if the generator guarantees it. The timestamp sorts values by millisecond, but IDs made in the same millisecond need a counter to stay in order. A simple random version does not keep them in order.

What is inside a UUID v7?

A 48-bit Unix timestamp in milliseconds, a 4-bit version, 12 bits of random or counter data, a 2-bit variant and 62 more random bits. The first 12 hex digits are the timestamp.

Can I get the time out of a UUID v7?

Yes. Remove the hyphens, take the first 12 hex digits and convert them to decimal. The result is Unix time in milliseconds. A decoder does this for you.

Generate your next UUID v7

If your platform has a built-in call, use it. If not, paste the function above into your project, or use the UUID v7 Generator for a one-off batch. Either way, now that you know how to generate a UUID v7, decode one result to confirm the version digit is 7 and the time is right.

Try these free tools

100% in your browser

Keep reading

All articles →