ULIDs: Benefits, Limitations, and Usage in ASP.NET Core
When it comes to assigning unique identifiers to entities or objects within an application, most developers rely on traditional mechanisms such as GUID or UUID. However, another interesting and potentially beneficial approach exists: Universally Unique Lexicographically Sortable Identifier (ULID).
In this blog post, we’ll delve into the concept of ULIDs, their advantages and limitations, and how they can be utilized within a .NET Core ASP.NET application.
What is a ULID?
A ULID is a 26-character identifier that is both unique and sortable in lexicographical order. It’s composed of two parts:
- a 10-character timestamp (in milliseconds)
- and a 16-character random (or entropy) part.
The timestamp ensures lexicographical order, and the random part ensures uniqueness. By being lexicographically sortable, ULIDs offer a unique advantage over traditional UUIDs which don’t retain the order of creation.
Output as a string a ULID looks like: 01H40CTHC0RNRGR77TFN01DW7M
- timestamp:
01H40CTHC0 - entropy:
RNRGR77TFN01DW7M
Benefits of ULIDs
There are several benefits to using ULIDs:
-
Time-Ordering: ULIDs are lexicographically sortable, meaning they retain information about when they were generated. This can be very useful in systems where the ordering of entities matters.
-
Highly Unique: With a 16-character random component, the probability of ULID collision is extremely low, similar to a UUID.
-
Web-Safe: ULIDs are encoded in Base32, which makes them URL-safe and usable in a wide range of scenarios.
-
Readable & Compact: Despite packing in a lot of information, ULIDs are still relatively compact and human-readable compared to a UUID.
Limitations of ULIDs
Though ULIDs offer numerous benefits, they come with a few limitations:
-
Concurrency Issues: If you generate multiple ULIDs at the same timestamp, the lexicographic ordering can get disrupted.
-
Non-Cryptographic: ULIDs aren’t suitable for scenarios where cryptographic randomness is required as the first part of a ULID is time-based.
Using ULIDs in .NET Core ASP.NET Applications
To generate ULIDs in .NET, you’ll need a library such as Ulid. You can install at the command line with:
> dotnet add package Ulid
Intallation instructions for other environments can be found on the Nuget.org page.
Once installed, you can generate a ULID as follows:
var newUlid = Ulid.NewUlid();
Console.WriteLine(newUlid.ToString());
It’s also possible to generate a ULID at the command line via the dotnet CLI with:
> dotnet ulid
In Entity Framework Core, you can use ULIDs as your entity IDs. Here’s an example:
public class Order
{
public Ulid Id { get; set; }
// Other properties...
}
To configure EF Core to use ULIDs, you’ll need to use the HasConversion method in your DbContext:
modelBuilder.Entity<Order>()
.Property(e => e.Id)
.HasConversion(
v => v.ToString(),
v => Ulid.Parse(v));
Summary
ULIDs represent an interesting alternative to traditional identifiers like UUIDs or integers, especially in systems where time-oriented sorting matters. By understanding their benefits and limitations, you can make an informed decision on whether they fit your ASP.NET Core application’s needs.