ulid-rs
A Rust implementation of ULID — Universally Unique Lexicographically Sortable Identifiers
Repository Health
Technical Analysis
ulid-rs implements the ULID specification in Rust: 128-bit identifiers that are lexicographically sortable by creation time, encode as a compact 26-character string, and remain collision-resistant like a UUID. Ulid::generate() produces monotonic-friendly IDs suitable for database primary keys, event ordering, and distributed ID generation without a central coordinator.
The crate supports no_std environments, optional serde serialization (either as the canonical string form or as the underlying u128), and optional integrations with postgres-types, uuid, and rkyv, making it easy to drop ULIDs into existing Rust data models and database schemas.
What You Get
Ulid::generate()andUlid::from_string()for creating and parsing 26-character ULIDs- Lexicographic sortability by creation timestamp, unlike random UUIDs
- Optional
no_stdsupport for embedded or constrained environments serdeserialization as either the canonical string or the inneru128- Optional interop with
postgres-types, theuuidcrate, andrkyvzero-copy serialization
Common Use Cases
- Generating sortable primary keys for database rows without a central auto-increment sequence
- Ordering distributed events or log entries by embedded creation timestamp
- Replacing random UUIDs where index locality and sort order matter for performance
- Serializing IDs directly into Postgres columns via the optional
postgresfeature
Under The Hood
Architecture - The crate’s core type is defined in lib.rs, storing a ULID as a single u128 combining a 48-bit timestamp with 80 bits of randomness; generator.rs implements a Generator that can produce monotonically increasing ULIDs within the same millisecond by incrementing the randomness component, while base32.rs handles the Crockford base32 encoding/decoding used for the canonical 26-character string representation.
Tech Stack - A small, dependency-light Rust crate (~1,500 lines, edition 2018) with all major dependencies gated behind Cargo features: rand for std generation, serde for serialization, postgres-types/bytes for Postgres interop, uuid for conversion, and rkyv for zero-copy deserialization — letting consumers pull in only what they need.
Code Quality - Tests are colocated in a tests/ directory plus inline unit tests, with lints.rust.keyword_idents = "warn" configured in Cargo.toml showing attention to lint hygiene; a separate cli/ subdirectory provides a small companion command-line tool for generating/inspecting ULIDs, kept out of the main library crate to avoid pulling CLI dependencies into library consumers.
API Design - The API is intentionally minimal — Ulid::generate(), Ulid::from_string(), Ulid::to_string() — mirroring the ergonomics of the widely-used uuid crate closely enough that switching between the two requires little relearning, while feature flags (rather than always-on dependencies) keep the default build small for users who don’t need Postgres or rkyv integration.
Used by 2 apps in this directory
Arroyo
Data Engineering · Analytics
A distributed stream processing engine written in Rust that lets you write SQL to run stateful, real-time computations over data streams with subsecond results.
Fluree DB
Databases
A temporal, verifiable graph database with git-like branching, integrated vector/text/geo search, and RDF/SPARQL/JSON-LD/openCypher support — benchmarked at 10.4x faster than the next database on the full Wikidata dump.