Fundamentals 8 min read

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.

Top Architect
Top Architect
Top Architect
Understanding ULID: A Lexicographically Sortable Unique Identifier and Its Advantages over UUID

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             80bits

Components

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.

0123456789ABCDEFGHJKMNPQRSTVWXYZ

Binary 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-py

Create 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

distributed systemsPythonUUIDunique identifierULID
Top Architect
Written by

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.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.