Every snippet below generates a standard 26-character ULID: a 48-bit millisecond timestamp followed by 80 bits of randomness, encoded in Crockford base32. All the libraries interoperate - a ULID generated in Python parses fine in Go, and any of them can be converted to UUID format because both are the same 128 bits.
Generate a ULID in Python#
Using python-ulid.
# pip install python-ulid
from ulid import ULID
ulid = ULID()
print(ulid) # 01JZKC5H4NW3F9M5T6R7X8Y9ZA
print(ulid.to_uuid()) # the same 128 bits as a UUID
print(ulid.datetime) # embedded timestampGenerate a ULID in JavaScript / TypeScript#
Using the ulid package, which works in Node.js and browsers. For IDs guaranteed to sort correctly within the same millisecond, use its monotonicFactory().
// npm install ulid
import { ulid, decodeTime } from 'ulid'
const id = ulid() // 01ARZ3NDEKTSV4RRFFQ69G5FAV
decodeTime(id) // 1469918176385 (ms since Unix epoch)Generate a ULID in Go#
Using oklog/ulid, the de facto standard Go implementation.
// go get github.com/oklog/ulid/v2
id := ulid.Make()
fmt.Println(id) // 26-char ULID
fmt.Println(ulid.Time(id.Time())) // embedded timestampGenerate a ULID in Rust#
Using the ulid crate.
// cargo add ulid
use ulid::Ulid;
let id = Ulid::new();
println!("{}", id); // 26-char ULID
println!("{:?}", id.datetime()); // embedded timestampGenerate a ULID in Java#
Using ulid-creator.
// implementation("com.github.f4b6a3:ulid-creator:5.2.3")
Ulid ulid = UlidCreator.getUlid();
String s = ulid.toString(); // 26-char ULID
UUID uuid = ulid.toUuid(); // the same 128 bits as a UUID
Instant time = ulid.getInstant(); // embedded timestampStore ULIDs in PostgreSQL#
There is no native ULID type - store ULIDs in a uuid column (16 bytes) rather than text (26 bytes). The pgx_ulid extension adds gen_ulid() if you want generation inside the database.
-- A ULID is 128 bits, so it fits a native uuid column.
-- Convert ULID <-> UUID in your app (or with this site) and store:
CREATE TABLE events (
id uuid PRIMARY KEY,
created_at timestamptz NOT NULL DEFAULT now()
);
-- PostgreSQL 18+ can generate time-ordered UUIDs (v7) natively:
CREATE TABLE events_v7 (
id uuid PRIMARY KEY DEFAULT uuidv7()
);