Zum Inhalt springen

⏱ When Milliseconds Aren’t Enough: A Pragmatic Take on ULID Overflow

This is a shortened version of an article originally published on my blog. You can find the full version here).

We all love ULIDs. They’re sortable, unique enough for most purposes, and a great alternative to UUIDs. The spec is pretty clear on how to handle things, but there’s one edge case that’s worth talking about: what do you do when you generate so many ULIDs in the same millisecond that you run out of random bits?

The official spec says to throw an overflow exception. And while that’s a valid, by-the-book answer, it’s not always the most practical one. In a high-throughput system, throwing an exception is a failure condition. It’s something you want to avoid.

So, in our C# ULID library, ByteAether.Ulid, we took a different path. When the 80-bit random part of the ULID overflows, we just increment the 48-bit timestamp by one millisecond.

Here’s why we think this is a better approach for real-world applications:

  • No More Overflow Exceptions! 🙌 This means more reliable systems, especially when you’re generating a ton of IDs.
  • Performance for the Win. 🚀 We sidestep the performance hit that comes with exception handling and other workarounds.
  • Keep Calm and Sort On. Your IDs will still be perfectly sortable within a single process.

We know this is a documented deviation from the spec. But let’s be real: cross-process millisecond ordering is already a bit fuzzy. A one-millisecond bump to the timestamp in a rare overflow situation is a small price to pay for a more resilient and performant system.

Check out ByteAether.Ulid on GitHub and see what you think. We’re betting that for most developers, this pragmatic approach to ULID generation is the way to go.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert