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

ULID is one of the leading competitors because it provides a unique ID that can be sorted.

In this article, I’ll discuss ULID’s features through examples so you can better understand when to use it.


Understand ULID and its usage

ULID stands for a universal unique alphabetically sorted identifier. It has over 271K NPM downloads and 1.7K GitHub Stars per week.

You can easily install the ULId NPM library and use it in your projects using the NPM I ulid command.

import { ulid } from'ulid; ulid();Copy the code

It has some amazing features that address some of the shortcomings of UUID. For example, when using UUID in a relational database, difficulties with data indexing can arise due to the lack of built-in sorting. In this case, you might be forced to include another attribute to make the data sortable.

In addition, UUID has some common problems with randomness, efficiency, and generation, which ULID addresses. So let’s take a closer look at ULID.

Use both timestamps and randomness

When you generate an ID using a UUID, it will only consider randomness or timestamps and generate a long string of 36 characters.

ULID, however, takes into account both randomness and timestamps to generate ids and encodes them into 26 strings (128 bits).

/ / UUID example
01FHZXHK8PTP9FVK99Z66GXQTX
Copy the code

The first 10 characters of ULID represent time stamps, and the second part of ULID represents randomness. Both parts are Base 32 encoded strings, represented by 48 and 80 bits, respectively.

For example, the breakdown of ULID above is as follows:

01 fhzxhk8ptp9fvk99z66gxqtx timestamp (48Bits) -01FHZXHK8P Random number (80 bits) - TP9FVK99Z66GXQTX
Copy the code

Note: use ULID Crockford Base32 alphabet code abcdefghjkmnpqrstvwxyz (0123456789). It does not include the I, L, O and U letters to avoid any accidental confusion.

UILD is sorted lexicographically

Dictionary collability is one of the most outstanding features of ULID.

ULID, as we already know, can sort. This feature of ULID allows developers to easily manage database-related tasks such as sorting, partitioning, and indexing.

For example, you don’t need to create an extra column to maintain the creation time of the record. Instead, you can use ULID’s timestamp representation to sort or partition data by creation time.

Note: The timestamp part of ULID is expressed in UNIX time (in milliseconds) and does not run out of space until 10889 AD.

High security of random numbers

Most random ID generators use unsafemath.random () to generate ids. ULID, however, prevents the use of math.random () by default and automatically determines the appropriate random number generator depending on the situation.

For example, it will use crypto. GetRandomValues in the browser and crypto. RandomBytes in the Node environment.

However, if you want to use math.random () in ULID, you need to explicitly allow this permission.

import { factory, detectPrng } from 'ulid'

const random_number_gen = detectPrng(true) 
const ulid = factory(random_number_gen)
Copy the code

Note: You can also use your own pseudo-random number generator to generate ULID.

Monotonous ULIDs with seed time

ULID allows you to get an ID with the same timestamp by passing the seed time. For example, if you want to create an ID with a timestamp of 2021-10-15, you need to pass the UNIX timestamp (in milliseconds) to the ulid() function.

ulid(1634263671000) // 01FJ0V986RA01G70YQ5Z0AMQE7
Copy the code

In addition, ULID allows you to create a series of ids with increasing values. All you need to do is create an ULId object using a Formal x/X Factory and pass the same time seed.

import { monotonicFactory } from'ulid'const ulid = monotonicFactory()
console.log(ulid(100000)); // 00000031N0J7R2B57M8YG73J7M
console.log(ulid(100000)); // 00000031N0J7R2B57M8YG73J7N
console.log(ulid(100000)); // 00000031N0J7R2B57M8YG73J7P
console.log(ulid(100000)); // 00000031N0J7R2B57M8YG73J7Q
console.log(ulid(100000)); // 00000031N0J7R2B57M8YG73J7R
Copy the code

Multilingual support

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

In addition, binary representations are available in more than 15 languages, including C++, Dart, Go, JavaScript, and Python.

JavaScript module support

ULID can be easily used with all types of JavaScript modules, including ES6+, CommonJS, and AMD.

// TypeScript , ES6+ Modules
import { ulid } from'ulid; ulid();// CommonJS
const ULID = require('ulid');
ULID.ulid();

// AMD
define(['ULID'].function (ULID) {
  ULID.ulid()
});

// Browser
<script src="https://unpkg.com/[email protected]/dist/index.umd.js"></script>
<script>
    ULID.ulid()
</script>
Copy the code

Other features

  1. You can generate 1.21e+24 unique ulids per millisecond.

  2. ULID is URL-safe because it does not use any special characters.

  3. Small package size – 2.5 kB (minified), 1.2kB (GZipped).

  4. The download time is about 1ms to 10ms.

  5. Shorter than UUID.

  6. Compatible with UUID 128 format.

The future emphasis

According to many experts in StackOverflow, there are no obvious drawbacks or limitations to using ULID.

However, case-insensitive and 80-bit randomness are the major shortcomings that developers have noticed in ULID. But its ability to sort dictionaries sets it apart from all the others.

Furthermore, if we consider the trend of ULID use over the past year, we can see that it is on the rise. Although far fewer downloads than the UUID, it has gained more than 150,000 users in the past year.

With all this functionality and my experience with UUID and ULID, this is a breeze for use cases that need sorting. So, don’t hesitate to use ULID for your next project.


Original: blog. Bitsrc. IO/ulid – v – uui…

By Chameera Dulanga