UUID v7 C#: Guid.CreateVersion7 and Earlier Options
.NET 9 added `Guid.CreateVersion7()`, making time-ordered UUIDs a built-in. On earlier versions a library fills the gap — and on SQL Server there is a byte-ordering quirk that catches everyone once.
The built-in
// .NET 9+
Guid id = Guid.CreateVersion7();
Guid at = Guid.CreateVersion7(DateTimeOffset.UtcNow); // explicit timestamp
// any version
Guid v4 = Guid.NewGuid();
Guid.NewGuid() remains v4. Before .NET 9, use the UUIDNext or Medo.Uuid7 package — both produce standard v7 values that interoperate with other languages.
Why v7 for keys
A v4 key scatters inserts across the clustered index, causing page splits and fragmentation that grow with the table. v7 appends at the end, like an identity column, while keeping client-side generation.
On SQL Server, a uniqueidentifier clustered primary key with random values is a well-known performance problem — v7 addresses the cause rather than working around it.
The SQL Server ordering trap
uniqueidentifier does not sort by byte order. SQL Server compares the last six bytes first, then earlier groups — so a v7 stored as uniqueidentifier does not sort by time in the database even though its bytes are time-ordered.
Options: store as BINARY(16) if you need in-database sorting, add an explicit created_at column and index that, or use NEWSEQUENTIALID() which is designed around SQL Server ordering but is server-generated only.
If you do store v7 in BINARY(16), write the bytes with id.ToByteArray(bigEndian: true), available since .NET 8. The parameterless ToByteArray() uses Microsoft's little-endian layout for the first three groups, which reverses the timestamp bytes and throws away the ordering you chose v7 for.
PostgreSQL and MySQL sort UUIDs by byte order, so v7 sorts correctly there with no special handling.
Entity Framework
modelBuilder.Entity<Order>()
.Property(o => o.Id)
.HasValueGenerator<Version7ValueGenerator>();
Version7ValueGenerator is not a class EF Core ships: it is a few lines you write yourself, a subclass of ValueGenerator<Guid> whose Next returns Guid.CreateVersion7() and whose GeneratesTemporaryValues returns false. EF Core does not switch to v7 on its own. Generating the id client-side lets you build related entities in one round trip. Avoid ValueGeneratedOnAdd with a database default if you also want the value before SaveChanges.
Frequently asked questions
Does .NET have a built-in v7 generator?
Yes, Guid.CreateVersion7() from .NET 9. Use UUIDNext or Medo.Uuid7 before that.
Why do my v7 GUIDs not sort in SQL Server?
uniqueidentifier compares the last six bytes first. Store as BINARY(16) or sort by a timestamp column.
Is Guid.NewGuid() version 7?
No, it is version 4 — random.