GUID (Globally Unique Identifier) is a 128-bit integer (16 bytes) that can be utilized across any computer or network when a unique identifier is needed.
The likelihood of such an identifier being duplicated is extremely low, which is why it is heavily used in distributed systems.
However, there are two interesting alternatives to classic GUIDs: one is coming with .NET 9, and the other is already available through a third-party library.
Problem with GUIDs?
UUIDs (Universally Unique Identifiers) are unique identifiers that can be generated independently, without the need for a central authority.
GUIDs are based on version 4 specification of UUIDs.
This is the most common UUID version and it ensures that UUIDs are generated from completely random numbers.
In C#, you can easily create one using Guid.NewGuid() in your application, and it has served us well:
Guid id = Guid.NewGuid();
03400154-6c0d-4a35-9c9b-e1d592314b46
fb2651e2-ebd5-400f-ac90-709e911e2726
cf8add80-4873-4140-ac7e-c443b4fc4359
c34f2564-f318-4475-a707-67564d2babfc
cf05c811-f68d-4ca7-88e3-842e03a17d6b
However, the problem with GUIDs, even though they are truly random, is that they are not time-ordered.
That's why I'm introducing you to GUID version 7 and ULIDs.
GUID Version 7
GUIDs Version 7 is coming soon with .NET 9 and, as you might expect, it is based on the version 7 UUID specification.
UUID Version 7 is a time-ordered UUID that is generated using a timestamp and random bits to create a unique identifier. The timestamp takes 48 bits, and the rest is reserved for random bits.
Guid.CreateVersion7() will generate version 7 UUIDs, and it also supports an overload that accepts a DateTimeOffset.
Guid id = Guid.CreateVersion7();
01925043-b259-78b7-a09d-c4e0dfc72f8e
01925043-b263-785d-9e72-bcef6aed97f2
01925043-b263-7f93-8942-3e4c2a4bea77
01925043-b263-76fb-a552-28d2e2ae11b7
01925043-b263-7120-9f39-b4b5f46aead3
However, there is a third-party alternative called ULID and you don't need to wait to start using it!
ULID
ULID (Universally Unique Lexicographically Sortable Identifier) is also a 128-bit identifier designed to be universally unique but also sortable, similar to GUID version 7.
Although ULIDs aren't as compact as purely numeric IDs, they are easier to read for humans compared to traditional UUIDs that use a hexadecimal format.
ULIDs are generated similarly to traditional GUIDs, using Ulid.NewUlid().
If needed, you can convert them to a hexadecimal format like GUIDs by using the .ToGuid() method.
Ulid ulidId = System.Ulid.NewUlid();
Guid guidId = System.Ulid.NewUlid().ToGuid();
01J984ESFAHA5ET2G6TYBDQE21
01J984ESFGTDYSK7S81T0F6KJG
01J984ESFGP1GARNECJMGGP87H
01925047-65f0-ed70-eef5-339ba852e4eb
01925047-65f0-6f66-476c-51fbb74b4df9
01925047-65f0-60bc-2644-188d8b5f2bbc
I was using this popular library with over 5 million downloads, check it out on GitHub, and if you like it, give it a star:
GitHub: Cysharp/UlidWhen I first started using ULIDs, GUID version 7 hadn't even been announced yet. When I ran some benchmarks, I was surprised by the results - ULIDs were faster than traditional GUIDs.
What's even more interesting is that when I benchmarked the new GUID version 7, I found that ULIDs were more than twice as fast compared to the new GUIDs.
| Method | Mean | Error | StdDev |
|---------------|------------|-----------|-----------|
| NewGuidV4 | 45.01 ns | 0.119 ns | 0.106 ns |
| NewGuidV7 | 82.69 ns | 0.821 ns | 0.768 ns |
| NewUlid | 29.90 ns | 0.098 ns | 0.092 ns |
| NewUlidToGuid | 31.12 ns | 0.185 ns | 0.164 ns |
Conclusion
Since .NET 9 is still not released, I hope they will make some performance improvements. In any case, if you want a time-ordered solution with good performance, you can use ULIDs.
If you want to conduct additional testing, you can find the source code here:
Source CodeNOTE: You will need .NET 9 SDK and Visual Studio Preview!
I hope you enjoyed it, subscribe and get a notification when new blog is up!
