Backend Development 7 min read

Understanding ULID: Features, Specification, and Python Usage Compared to UUID

This article explains what ULID is, why it can be a better alternative to UUID, outlines its key characteristics and specification, and provides practical Python examples for generating and handling ULIDs in distributed backend systems.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Understanding ULID: Features, Specification, and Python Usage Compared to UUID

ULID (Universally Unique Lexicographically Sortable Identifier) is introduced as a globally unique identifier that combines a millisecond‑precision timestamp with a high‑entropy random component, offering collision‑free generation and lexicographic ordering.

Why not choose UUID – UUID has five versions, each with drawbacks such as reliance on MAC addresses, potential fragmentation, or pure randomness without ordering. UUID4 is common but still carries a risk of collisions.

Unlike UUID, ULID encodes both time and randomness, providing 1.21e+24 possible random values per millisecond, eliminating collision risk and producing a more readable string.

ULID Features

128‑bit compatibility with UUID

1.21e+24 unique IDs per millisecond

Lexicographic (alphabetical) sorting

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 current ULID specification (as implemented in python(ulid-py) ) defines a binary layout of 48‑bit timestamp and 80‑bit randomness.

01AN4Z07BY      79KA1307SR9X4MV3

|----------|    |----------------|
 Timestamp          Randomness
 10chars            16chars
  48bits             80bits

Components

Timestamp

48‑bit integer representing UNIX time in milliseconds

Valid until year 10889, ensuring ample space

Randomness

80‑bit random number, preferably generated with cryptographic quality

Sorting

The leftmost characters must appear first and the rightmost last, using the default ASCII set; ordering cannot be guaranteed for IDs generated within the same millisecond.

Encoding

ULID uses Crockford's Base32 alphabet (0123456789ABCDEFGHJKMNPQRSTVWXYZ) which omits I, L, O, and U to avoid confusion.

Binary Layout and Byte Order

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 involvement in key generation

Use in distributed systems as a UUID alternative, providing global uniqueness with millisecond ordering

Leverage the embedded timestamp for time‑based sharding or partitioning

Sort records by ULID when millisecond precision is sufficient, avoiding a separate timestamp column

Usage (Python)

Install the library:

pip install ulid-py

Create a new ULID:

>> import ulid
>>> ulid.new()

Generate a ULID from an existing UUID:

>> import ulid, uuid
>>> value = uuid.uuid4()
>>> value
UUID('0983d0a2-ff15-4d83-8f37-7dd945b5aa39')
>>> 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)

Interact with a ULID object:

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

Open‑source repository: https://github.com/ahawker/ulid

backendPythonUUIDULIDidentifier
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

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.