UUIDs vs. ULIDs
ULID vs UUID by ali alachkar

UUIDs vs. ULIDs

Why do we use UUIDs?

UUID is one of the most commonly used universal identifiers in software development. However, new alternatives have challenged its existence over the past few years.

Most systems have moved on from using basic sequential IDs to using UUIDs (Universally Unique IDentifiers), with whom they achieve universal uniqueness across the whole system, because the probability of collision between two UUIDs is so minuscule that we can say it’s practically 0.

?

Another benefit that these IDs provide is their unpredictability. In a RESTful API scenario where we attach IDs to the URL, it would be impossible for an ‘outside’ user to guess the previous or next ID of a customer in our system:

Using sequential IDs (easy guess of prev user in the system: 15–1=14 ): https://ali-alachkar.netlify.app/api/ideas/15
Using UUIDs (no way we’re guessing the prev or next user in our system): https://ali-alachkar.netlify.app/api/ideas/11c105dc-74e4–41b2-a014-bced748111a3

???? What is UUID?

A universally unique identifier (UUID), also known as a globally unique identifier (GUID), uses 128 bits to store random identifiers. For example, the number of random version-4 UUIDs that need to be generated in order to have a 50% probability of at least one collision is 2.71 quintillion. This number is equivalent to generating 1 billion UUIDs per second for about 85 years.

UUIDs are often represented as 32-digit hexadecimal strings:

123e4567-e89b-12d3-a456-426614174000        

Pros

  • Decentralized way of generating IDs
  • No way of getting the same ID across different applications

Cons

  • No way of sorting

Then, What is ULID?

ULIDs are also using 128 bits to store identifiers, but this time the first 48 bits are used for timestamps while the rest of the 80 bits are used for randomness. This is a key difference between it and UUID because it gives you the possibility to sort them. ULID is even lexicographically sortable, which gives us the ability to sort them as strings!

As the identifier is now bound to timestamps, we can create as many as 1.21e+24 unique ULIDs per millisecond. While UUID theoretically can't be duplicated in practice, it happens that some faulty implementations of concepts leave people with multiple identifiers for different data. While human error is still possible with ULIDs, it's a lot more unlikely.

ULIDs are represented as a 26-character string:

0001EHZADJ5FDB1RJS00JK7VD8        

From this ULID we can extract timestamps and random parts:

2019-07-05 15:49:06 5FDB1RJS00JK7VD8        
Comparison between ULID and UUIDv4

?? Why should we consider ULIDs?

Universally Unique Lexicographically Sortable Identifier

It comes with some amazing features that resolve some of the drawbacks of UUID. For example, when using UUID with relational databases, there can be difficulties indexing the data due to the lack of inbuilt ordering. In such situations, you might be forced to include another attribute to make the data sortable.

ULIDs offer everything that UUIDs offer, but in addition:

  1. They are sortable. Having a time component embedded within them, ULIDs can be sorted in the order of their generation.
  2. They have a compact string representation: ULIDs are typically represented as a 26-character string, which is shorter than the standard 36-character representation of UUIDs. (thus saving storage space and offering more efficiency when working with databases or transmitting data over the network).
  3. UUID has some common issues regarding its randomness, efficiency, and seeding, addressed by ULID.



?? The structure of a ULID

ULID consists of two main components:

  • timestamp portion (48 bits)
  • randomly generated portion (80 bits)

which are then combined into one, forming the 26-character and 128-bit compatible ID.

The first 10 characters of the ULID represent the timestamp, and the second part of the ULID represents randomness. Both of these parts are base 32-encoded strings and are represented using 48 bits and 80 bits, respectively.


?? What do we gain from the sortability of ULIDs?

The main gain, in my opinion, is simplified indexing. Sorting ULIDs simplifies the process of indexing and querying data by creation time.

By utilizing ULIDs as a part of the primary key or indexed field in databases or search engines, we can achieve efficient sorting of records based on their creation order. (removing the need to explicitly add a created_on field to the DB table)

By sorting ULIDs in ascending order, we can retrieve data in the order it was created. This removes the need to explicitly add a created_on field to our table and write more extensive database queries.


? ULIDs and security

ULID takes a different approach compared to many random ID generators that, for example, in JavaScript, rely on the potentially unsafe Math.random() function. ULID addresses this concern by disabling the usage of Math.random() by default.

Instead, ULID automatically selects an appropriate random number generator based on the specific situation or context in which it is being used. But by default, it uses CSPRNGs (system-provided or platform-specific ones, coming from external libraries for that purpose).

ULIDs can also leverage system randomness or configurable options as tools for generating random characters.


?? Multi-Language Support

ULID supports nearly 50 languages, including JavaScript, Java, C++, Dart, Python, and .NET.

Also, binary representations are available for more than 15 languages, including C++, Dart, Go, JavaScript, and Python.


?? Future Focus

Based on many expert opinions on StackOverflow, there are no significant disadvantages or limitations to using ULID.

However, case insensitivity and 80-bit randomness are the main disadvantages developers notice in ULID. But its lexicographic sorting ability makes it unique among all the others.


? Examples for UUIDs and ULIDs

ULID (Universally Unique Lexicographically Sortable Identifier) examples:

A ULID is a 128-bit label. It is monotonically rising, sortable, and has millisecond precision.

01ES8M1EYQNCPG8P0ZQSYZ75RP
01ES8MBQAKTZWTGSZMZP48T0DA
01ES8MCA2N8DRJDW86XQRZPD96
01ES8MEVDTRN3H04J9FVWQ56B7
01ES8MH69Q8ET3HYTM88D5BT5T
01ES8MK0P4FGVPD9J3TAVGFCV0        

UUID (Universally Unique Identifier) examples:

f47ac10b-58cc-4372-a567-0e02b2c3d479
d8e92261-1040-46c3-b85e-774d8a143a02
5f71fe9e-7385-4c42-89e9-61a8c24b25c5
92e26f80-0b6f-4cf4-b52a-5b3b7f5e1a49
b7e646d3-e618-4e75-9546-8fc081a4fb2b        

THANK YOU FOR READING ??


要查看或添加评论,请登录

Ali Alachkar的更多文章

  • Unpacking in Python

    Unpacking in Python

    Unpacking is a powerful technique that allows us to peel apart a Python data structure and pass the contents of that…

  • How do I prevent and recover from a ransomware attack?

    How do I prevent and recover from a ransomware attack?

    ?? What is ransomware? Ransomware is malicious software designed to block access to computer systems or files until a…

    1 条评论
  • Logger best practices!

    Logger best practices!

    Today, we will talk about some of the best practices for implementing loggers in your application! What's logging?…

    1 条评论
  • ?? What is the Slowloris attack?

    ?? What is the Slowloris attack?

    A Slowloris attack is inspired by this animal’s behavior and appearance. It is a DoS attack that imitates a normal HTTP…

社区洞察

其他会员也浏览了