UUID v7 Generator

Time-ordered UUIDs that sort chronologically by creation time. The same identifier you'd want as a database primary key — random enough to be unguessable, sequential enough to play well with B-tree indexes.

Output options
Case
Bulk delimiter
Click Generate to produce UUID v7 values.

About UUID v7

UUID v7 is the headline addition of RFC 9562, published in May 2024. It addresses one of the longest-standing complaints about UUID v4 as a database primary key: random insertion order causes B-tree index fragmentation and degrades insert performance on high-write tables.

v7 fixes this by placing a 48-bit Unix millisecond timestamp at the start of the UUID. The remaining bits, after the version and variant markers, are filled with cryptographically secure random data. The result is a UUID whose values sort chronologically — values generated milliseconds apart compare adjacent, values generated months apart compare far apart. Inserting v7 UUIDs into a B-tree index has the same cache and page-locality characteristics as inserting auto-incrementing integers, while preserving UUID's distributed-generation property.

The timestamp uses standard Unix milliseconds rather than the unusual Gregorian-epoch precision counter inherited by v1 and v6. This makes v7 simpler to generate, simpler to decode, and easier to reason about.

When to use UUID v7

v7 is the right default for new projects in most scenarios where UUIDs are appropriate:

  • Database primary keys, especially for tables with significant insert volume. The sort property dramatically reduces index fragmentation compared to v4. For the deeper trade-off against integer keys, see UUID vs auto-increment primary keys; for the choice against a shorter URL-friendly format, see NanoID vs UUID.
  • Time-ordered identifiers for events, logs, or audit records, where decoding the timestamp from the ID itself is useful.
  • Distributed system identifiers where multiple nodes generate IDs concurrently and you want global ordering without coordination. v7 is the usual default here; for how it compares to Snowflake, ULID, and KSUID, see generating IDs in distributed systems.

v4 remains the better choice when:

  • Creation time is sensitive. v7 UUIDs leak millisecond-precision creation timestamps. If users shouldn't be able to determine when an account was created, when a record was added, or what order resources were provisioned in, use v4.
  • Maximum randomness is required. v7 has 74 random bits (after timestamp, version, and variant). v4 has 122. For most uses 74 bits is more than adequate, but in extreme high-volume scenarios where collision avoidance is paramount, v4's additional entropy may matter.

Implementation considerations

.NET byte order. The .NET 9+ Guid.CreateVersion7() API produces RFC-compliant UUIDs, but Guid.ToByteArray() returns bytes in the native little-endian layout, which breaks v7's sort property when persisted as binary. Use Guid.TryWriteBytes(span, bigEndian: true, out _) and new Guid(span, bigEndian: true) at any boundary where bytes are compared. See our dedicated article for a full discussion.

SQL Server. SQL Server's uniqueidentifier type uses a non-standard byte layout, and its sort order on that type is genuinely unusual. For v7 UUIDs where sortability matters, store as BINARY(16) in RFC byte order rather than as uniqueidentifier.

Other databases. PostgreSQL, MySQL, MariaDB, and SQLite all sort UUIDs by their natural byte order when stored correctly. Write the bytes in RFC order and sortability is preserved. For a PostgreSQL-specific walkthrough — where to generate v7, index density, and the gotchas — see UUID v7 in PostgreSQL.

Clock skew across systems. Because v7 embeds the generating system's clock, IDs generated on machines with skewed clocks may sort in an unintuitive order. For most use cases this is harmless — the IDs remain globally unique and roughly chronological. For applications that depend on strict total ordering, use a centralised generator or rely on database-assigned sequence numbers instead.

Generating v7 in code

C# (.NET 9+)

var id = Guid.CreateVersion7();
// 019e2814-c14b-7067-b1bb-732a7ac34ee4

// For binary storage — use bigEndian: true!
Span<byte> bytes = stackalloc byte[16];
id.TryWriteBytes(bytes, bigEndian: true, out _);

PostgreSQL 18+

SELECT uuidv7();

Python (uuid7 package)

from uuid_utils import uuid7
id = uuid7()

FAQ

Why use v7 instead of v4?
v7's time-ordered bytes mean newly inserted rows land at the right edge of a B-tree primary key index, the way a sequential integer does. v4, being uniformly random, scatters writes across the whole index and forces more page splits. For high-insert tables, v7 measurably reduces index fragmentation and improves write throughput.
Is the embedded timestamp leaky?
Yes — anyone with a v7 value can read its creation time to ms precision. That's fine for internal database keys. For public-facing identifiers where creation order is sensitive (session tokens, password-reset links), stick with v4.
Can two v7s generated in the same millisecond collide?
Effectively no. After the 48-bit timestamp, v7 has 74 random bits (12 in rand_a + 62 in rand_b) — enough that collisions within a single ms remain astronomically unlikely.
Are v7s lexicographically sortable within the same millisecond?
RFC 9562 only guarantees sortability across milliseconds. Implementations may opt into a sub-ms monotonic counter (RFC 9562 §6.2 monotonicity guidance); .NET's Guid.CreateVersion7() does not, so two v7s generated in the same ms can appear in either order. For most use cases — primary keys, event timestamps — this doesn't matter.
What's the .NET byte-order issue?
Guid.ToByteArray() with no arguments returns the bytes in little-endian field order — a legacy of System.Guid's Windows-COM origins. That layout silently breaks v7's sortability when you store the bytes in a binary column. Use TryWriteBytes(..., bigEndian: true, ...) instead. Read the full explanation →
An unhandled error has occurred. Reload ×