Databases 7 min read

Understanding ULID: A Lexicographically Sortable Unique Identifier and Its Python Implementation

ULID (Universally Unique Lexicographically Sortable Identifier) offers a 128‑bit, time‑based and random identifier that is URL‑safe, sortable, and more collision‑resistant than UUID, with detailed specifications, binary layout, and Python usage examples including generation, conversion, and component extraction.

Architecture Digest
Architecture Digest
Architecture Digest
Understanding ULID: A Lexicographically Sortable Unique Identifier and Its Python Implementation

ULID (Universally Unique Lexicographically Sortable Identifier) is presented as an alternative to UUID, providing a 128‑bit identifier that combines a millisecond‑precision timestamp with a large random component, resulting in lexicographically sortable, URL‑safe IDs with a negligible risk of collision.

Unlike UUID’s five versions—where version 1 requires a MAC address, version 2 replaces part of the timestamp with UID/GID, versions 3 and 5 rely on hash functions, and version 4 is purely random—ULID merges time and randomness, offering better ordering and readability.

Key ULID characteristics:

128‑bit compatibility with UUID

1.21×10²⁴ unique IDs per millisecond

Lexicographic (dictionary) ordering

Encoded as a 26‑character Crockford Base32 string (no I, L, O, U)

Case‑insensitive and URL‑safe

Monotonic ordering within the same millisecond

ULID specification: The identifier consists of a 48‑bit timestamp (UNIX time in milliseconds) and an 80‑bit random component. The binary layout is encoded in network byte order across 16 bytes.

01AN4Z07BY      79KA1307SR9X4MV3
|----------|    |----------------|
Timestamp          Randomness
10 chars           16 chars
48 bits            80 bits

Components:

Timestamp

48‑bit integer representing UNIX time in milliseconds

Valid until the year 10889

Randomness

80‑bit random number, preferably generated with a cryptographically secure source

Sorting: Characters are ordered lexicographically; the leftmost character is the most significant. Within the same millisecond, strict ordering cannot be guaranteed.

Encoding: Uses Crockford’s Base32 alphabet (0123456789ABCDEFGHJKMNPQRSTVWXYZ) to improve efficiency and readability.

0123456789ABCDEFGHJKMNPQRSTVWXYZ

Binary layout and byte order: The 16‑byte representation is big‑endian (network byte order).

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          32_bit_uint_time_high          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   16_bit_uint_time_low   |   16_bit_uint_random   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          32_bit_uint_random            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          32_bit_uint_random            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Typical use cases:

Replace auto‑increment primary keys in databases without DB involvement

Distributed systems needing globally unique, time‑ordered IDs

Database sharding/partitioning based on embedded timestamps

Sorting records by ULID instead of a separate timestamp column when millisecond precision suffices

Python usage (ulid‑py library):

pip install ulid-py

Generate 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 ULID components:

>> u = ulid.new()
>>> u.timestamp()
>>> u.randomness()

For more information, see the project repository at https://github.com/ahawker/ulid .

distributed systemsPythonunique identifierULIDUUID alternative
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

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.