A Conversational Guide to ULID (Universally Unique Alphabetically Sortable Identifier)
Previously, many people have been using UUIDs to ensure unique Id fields. However, the randomness of UUIDs makes them non-sortable. For example, you might generate a UUID starting with 47 one second, and then the next second it starts with 36. This randomness can lead to efficiency problems in databases like MySQL, which need to update multiple pages, especially when dealing with large amounts of data.
Because of this issue, the concept of ULID was introduced. ULIDs are generated to be lexicographically sortable. Besides this sortable feature, ULIDs have several other characteristics:
- They are compatible with UUIDs, both using 128 bits.
- They support millisecond-level unique Ids (ULIDs may not be suitable if your usage exceeds this level).
- They are URL-safe, using an encoding method that results in only 26 characters, compared to the 36 characters of UUIDs.
- They are case-insensitive.
While ULID seems to have advantages over UUID, the first 48 bits of ULID are a timestamp. This could pose security issues: if someone knows the timestamp, they could potentially guess some Ids by generating the remaining 80 bits.
Another concern is that unlike UUIDs, ULIDs don’t have an RFC standard. There’s only a GitHub Spec available, so whether a package correctly implements ULID depends on the developer’s integrity or requires you to do additional testing yourself.
Regardless of which method you use to generate Ids, it’s best to understand the differences to choose the most suitable Id system for your application. (I didn’t realize there could be issues using UUIDs as PKs until I looked into this…😭)