Highlights
- 🚀 Bulk generation —
GuidV7.Fill(Span<Guid>)/NewGuids(count)(and theGuidV8Timemirrors) reserve one counter block,
capture one timestamp, and make one RNG call for the whole batch. Roughly 11× faster than callingGuid.CreateVersion7in a
loop, and still zero-alloc. - 🕰
TimeProvideroverloads — every generation path, single-call and bulk, now accepts an injected clock on .NET 8+.
FakeTimeProvider-style testing without threading raw timestamps through your code. - 🗝 EF Core value generation — one line in
ConfigureConventionsand everyGuid,SequentialGuid, andSequentialSqlGuid
primary key gets a real RFC 9562 v7 value client-side onAdd. No database round-trip, retry-safe, composite keys included, and
explicit per-property configuration always wins. - 🍃 MongoDB —
MongoSequentialGuidGeneratorcan now emit v7 ids vianew MongoSequentialGuidGenerator(SequentialGuidType.Rfc9562V7).Instancestill emits v8 — no silent behavior change.
New APIs
Core (SequentialGuid, .NET 8+ assets):
GuidV7.Fill(Span<Guid>)/FillSql(Span<Guid>)/NewGuids(int)/NewSqlGuids(int)— each with no-arg,long unixMilliseconds, andTimeProvidertimestamp formsGuidV8Time.Fill/FillSql/NewGuids/NewSqlGuids— same surface withDateTimeas the deterministic formGuidV7.NewGuid(TimeProvider)/NewSqlGuid(TimeProvider)and theGuidV8Timeequivalents
Batches that would exceed the counter space (2²⁶ for v7, 2²² for v8) throw ArgumentOutOfRangeException — no silent wrap, no
out-of-order ids.
EF Core (SequentialGuid.EntityFrameworkCore):
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
configurationBuilder.AddSequentialGuidValueConverters();
configurationBuilder.UseSequentialGuidValueGeneration();
// or: UseSequentialGuidValueGeneration(sqlServerByteOrder: true);
}
The four generators (SequentialGuidValueGenerator, SequentialSqlGuidValueGenerator,
SequentialGuidStructValueGenerator, SequentialSqlGuidStructValueGenerator) are public for
explicit HasValueGenerator<T>() wiring. Includes a sentinel pin that works around EF 8/9
computing struct sentinels via Activator.CreateInstance (fixed in EF 10).
Performance
Measured with BenchmarkDotNet on Intel Core Ultra 9 185H, .NET 10.0.9 — regenerate with
dotnet run -c Release --project benches/Benchmarks -- --filter *BclComparison*:
┌──────────────────────────────────┬──────────────┬──────────┬───────────┐
│ Method │ Mean │ Ratio │ Allocated │
├──────────────────────────────────┼──────────────┼──────────┼───────────┤
│ Guid.NewGuid │ 44.46 ns │ 1.00 │ - │
├──────────────────────────────────┼──────────────┼──────────┼───────────┤
│ Guid.CreateVersion7 │ 65.09 ns │ 1.46 │ - │
├──────────────────────────────────┼──────────────┼──────────┼───────────┤
│ GuidV7.NewGuid │ 82.59 ns │ 1.86 │ - │
├──────────────────────────────────┼──────────────┼──────────┼───────────┤
│ 'Guid.CreateVersion7 ×1000 loop' │ 67,284.17 ns │ 1,513.81 │ - │
├──────────────────────────────────┼──────────────┼──────────┼───────────┤
│ 'GuidV7.NewGuid ×1000 loop' │ 88,345.82 ns │ 1,987.67 │ - │
├──────────────────────────────────┼──────────────┼──────────┼───────────┤
│ 'GuidV7.Fill ×1000 bulk' │ 6,210.75 ns │ 139.73 │ - │
└──────────────────────────────────┴──────────────┴──────────┴───────────┘
The trade-off is honest: the monotonic counter and SQL-capable layout cost a few nanoseconds per
single call versus the BCL's Guid.CreateVersion7. What you get for it: strict same-millisecond
ordering under concurrency, SQL Server byte-order support, timestamp round-tripping, .NET
Framework / .NET Standard reach — and where throughput matters, the bulk API more than repays it.
The README has a new Why not Guid.CreateVersion7? (https://github.com/buvinghausen/SequentialGuid#why-not-guidcreateversion7)
section with the full comparison.
Fixes
- 🎲 The legacy-TFM GetInt32 counter-seeding helper now uses unbiased mask-and-reject sampling
(it previously combined GetNonZeroBytes with a double-modulo fold — harmless in practice
since it only seeded startup counters, but biased nonetheless).
Compatibility
- SemVer minor — fully additive. No breaking changes, no behavior changes to existing APIs.
- Bulk generation and TimeProvider overloads ship in the .NET 8+ assets; .NET Framework 4.6.2
and .NET Standard 2.0 consumers keep the existing single-call surface.
- The EF Core package targets EF Core 8 / 9 / 10 on net8.0 / net9.0 / net10.0.
- MongoSequentialGuidGenerator.Instance still emits v8 time-based GUIDs.
Verified
- 31,605 tests green across net11.0 / net10.0 / net9.0 / net8.0 / net472, zero warnings with
warnings-as-errors.
- Native AOT smoke tests (core + NodaTime, and a new EF Core smoke app) publish and run in CI.
- Bulk/single-call interleaving is regression-tested with deterministic timestamps on both
time-based generators — counter blocks and single-call slots provably never overlap.
Full Changelog: https://github.com/buvinghausen/SequentialGuid/compare/v6.1.0...v6.2.0