Understanding ULID: A Lexicographically Sortable Unique Identifier and Its Advantages over UUID
This article explains ULID (Universally Unique Lexicographically Sortable Identifier), compares it with UUID, details its timestamp‑based and random components, lists its features and binary layout, and shows how to generate and use ULIDs in Python for distributed systems.
ULID (Universally Unique Lexicographically Sortable Identifier) is a 128‑bit identifier that combines a 48‑bit timestamp (millisecond precision) with an 80‑bit random component, offering lexicographic ordering and collision‑free generation.
Why Not Choose UUID
UUID has five versions, each with drawbacks such as reliance on MAC addresses, limited randomness, or potential fragmentation. UUID4, the most common, is purely random and still carries a non‑zero risk of collisions.
Unlike UUID, ULID’s timestamp component provides monotonic ordering, and its massive random space (1.21e+24 values per millisecond) eliminates collision risk while producing a more readable string.
ULID Features
128‑bit compatibility with UUID
1.21e+24 unique ULIDs per millisecond
Lexicographically sortable (alphabetical order)
Encoded in 26 characters using Crockford's Base32
Case‑insensitive and URL‑safe (no special characters)
Monotonic ordering within the same millisecond
ULID Specification
The ULID consists of a 48‑bit timestamp (UNIX time in milliseconds) and an 80‑bit randomness value, both encoded with Crockford's Base32 alphabet (0123456789ABCDEFGHJKMNPQRSTVWXYZ).
01AN4Z07BY 79KA1307SR9X4MV3
|----------| |----------------|
Timestamp Randomness
10chars 16chars
48bits 80bitsComponents
Timestamp
48‑bit integer representing UNIX time in milliseconds
Valid until year 10889, ensuring space will not be exhausted
Randomness
80‑bit random number, preferably generated with cryptographic quality
Sorting
Characters are ordered lexicographically using the default ASCII set; ordering cannot be guaranteed for IDs generated within the same millisecond.
Encoding
Crockford's Base32 excludes I, L, O, and U to avoid confusion; the resulting string is URL‑safe.
0123456789ABCDEFGHJKMNPQRSTVWXYZBinary Layout and Byte Order
Components are encoded as 16 octets in network byte order (big‑endian).
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 32_bit_uint_time_high |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 16_bit_uint_time_low | 16_bit_uint_random |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 32_bit_uint_random |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 32_bit_uint_random |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+Application Scenarios
Replace auto‑increment primary keys in databases, eliminating DB‑side key generation.
In distributed systems, serve as a globally unique, time‑ordered alternative to UUID.
Use the embedded timestamp for time‑based sharding or partitioning.
When millisecond precision ordering is acceptable, sort records directly by ULID instead of a separate timestamp column.
Usage (Python)
Install the library:
pip install ulid-pyCreate a new ULID:
>> import ulid
>>> ulid.new()Convert an existing UUID to ULID:
>> import ulid, uuid
>>> value = uuid.uuid4()
>>> ulid.from_uuid(value)Create a ULID from a specific timestamp:
>> import datetime, ulid
>>> ulid.from_timestamp(datetime.datetime(1999, 1, 1))Generate a ULID from custom randomness:
>> import os, ulid
>>> randomness = os.urandom(10)
>>> ulid.from_randomness(randomness)Access components of a ULID object:
>> u = ulid.new()
>>> u.timestamp()
>>> u.randomness()Repository: https://github.com/ahawker/ulid
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.