Database security is really important when it comes to building custom web applications. One of the most common mistakes people make when creating their database is using regular IDs.
Not only are they in chronological order and visible with just an inspect on the network of dev tools, but also finding vulnerabilities and reverse-engineering your web app can be 10 times easier.
Today, we are going to see one alternative to both UUID and regular IDs. I've implemented this on all of my custom website apps in the past year.
What is ULID
To begin with, you can read the ulid spec here and see for yourself, but let's cover some important facts. ULID stands for Universally Unique Lexicographically Sortable Identifier. As its name implies, it is unique and sortable, and it looks like this 01ARZ3NDEKTSV4RRFFQ69G5FAV
.
It has implementations for almost every language and can replace the other two in almost every scenario. In other words, wherever you need indexing and sharding, you can use ULID.
Compatible
It is 128-bit compatible with UUIDs, which means they are the same size but shorter in length. So, you can easily replace UUIDs in databases or object storage systems.
It can also be used on Kafka and RabbitMQ.
Also, you can generate 1.21e+24 unique ULIDs per millisecond. This is not really important whether it is lower or higher than UUIDs because it is already a very large number.
Don't forget that it is more URL-friendly than UUIDs.Comparisons
Feature |
ID (id ) |
UUID (uuid ) |
ULID (ulid ) |
---|---|---|---|
Format | Integer | 128-bit hexadecimal string | 128-bit string |
Generation | Sequential | Random or time-based | Time-based and random |
Readability | Simple and short | Long and complex | Shorter, human-readable |
Uniqueness | Not guaranteed across shards | Globally unique | Globally unique |
Ordered | Yes | No | Yes |
Generation speed | Fastest | Slower than id
|
Slower than id
|
Use across distributed systems | Poor | Excellent | Excellent |
Time-based | No | Optional (UUID v1) | Yes |
Collision risk | Low in single instance | Extremely low | Extremely low |
Storage efficiency | High | Lower | Lower |
Implementation complexity | None | More complex | Slightly more complex |
Implementation
It can be very simple to implement. I am going to show one example in Kotlin with Spring Boot to demonstrate how simple it is. Just find a library that generates ULIDs and update your models.
import com.github.f4b6a3.ulid.UlidCreator
@Entity
@Table(name = "users")
data class UserModel(
@Id
var id: String = UlidCreator.getUlid().toString(),
// other fields
) : UserDetails {
// yourcode
}
Is it worth it ?
I am not going to cover all the reasons why Ulid is better, but in the end, it's up to your personal preference. I believe in the long run it gives you an advantage. Even if you create a small API, switching early on to Ulid is a benefit. Having to change mid-way through production can be challenging.
Conclusion
In conclusion, ULIDs offer a compelling alternative to traditional UUIDs and simple numeric IDs, particularly for applications requiring both uniqueness and sortability.
Their compatibility with UUID standards, coupled with features like time-based generation and global uniqueness, make ULIDs particularly suitable for distributed systems where sorting and scalability are crucial. While the implementation may be slightly more complex than basic IDs, the long-term benefits in terms of system performance and maintainability can justify the initial effort.
Thanks for reading, and I hope you found this article helpful. If you have any questions, feel free to email me at kourouklis@pm.me, and I will respond.
You can also keep up with my latest updates by checking out my X here: x.com/sotergreco
Top comments (0)