uuid-utils

A Rust-powered, drop-in replacement for Python's uuid module that generates UUIDv1-v8 much faster than the standard library.

Library
PyPI
v0.17.0
368stars
BSD 3-Clause License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
79/100Good
Development Activity88
Maintenance92
Community56
Maturity52
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
80/100Excellent
Architecture80
Code Quality82
Innovation72
Learning Curve85

uuid-utils replaces Python’s built-in uuid module with a Rust extension built on the uuid and pyo3 crates, exposing the same uuid1/uuid3/uuid4/uuid5/uuid6/uuid7/uuid8 functions and UUID object surface while running significantly faster for both generation and parsing. It targets applications that mint large volumes of identifiers — request IDs, database primary keys, distributed tracing spans — where the stdlib implementation’s overhead becomes measurable.

Beyond the core versions supported by the standard library, uuid-utils adds first-class support for UUIDv6 (a reordered, sortable variant of v1) and UUIDv7 (Unix-timestamp-ordered, ideal for time-sortable database keys) and UUIDv8 (fully custom, user-defined payload), none of which are available in Python’s stdlib uuid module prior to newer CPython releases.

A uuid_utils.compat submodule returns genuine stdlib uuid.UUID instances instead of the crate’s own UUID subclass, so frameworks like Django that use isinstance checks against the standard library’s type keep working while still benefiting from the faster Rust-side generation logic.

What You Get

  • All seven UUID versions in one package — v1, v3, v4, v5, v6, v7, and v8 — including v6/v7/v8 which the stdlib historically lacked
  • A uuid_utils.compat module that returns real stdlib uuid.UUID instances for frameworks (e.g. Django) that require the exact standard-library type
  • Cross-platform prebuilt wheels for Linux (x86_64/i686/aarch64/armv7/ppc64le), macOS, and Windows, plus PyPy and free-threaded CPython 3.14t builds
  • A getnode()/MAC-address-based node ID resolver with graceful fallback to a random node when no MAC is available, matching stdlib semantics
  • RNG reseeding after os.fork() via os.register_at_fork, avoiding duplicate UUIDs across forked worker processes
  • Published microbenchmarks (via pytest-codspeed and CodSpeed CI) comparing every operation against the stdlib and the compat layer

Common Use Cases

  • Minting request IDs or trace IDs in high-throughput API services where per-request UUID generation overhead adds up
  • Generating UUIDv7 primary keys for databases that benefit from time-ordered, index-friendly identifiers
  • Dropping into an existing Django or Flask codebase that imports the stdlib uuid module, via uuid_utils.compat, without touching call sites
  • Bulk-generating large batches of UUIDs (e.g. for test fixtures, data seeding, or ETL pipelines) where raw throughput matters
  • Building distributed systems that need sortable, collision-resistant identifiers (UUIDv6/v7) without hand-rolling timestamp-prefixed IDs

Under The Hood

Architecture The project is a thin two-layer system: a Rust extension crate (src/lib.rs) compiled via PyO3/maturin into a _uuid_utils native module, and a small pure-Python package (python/uuid_utils/) that re-exports the native symbols and adds Python-level conveniences. The Rust side defines a #[pyclass] UUID struct wrapping the uuid crate’s Uuid type, implements Python dunder methods (__int__, __str__, __repr__, __richcmp__, __hash__, __setattr__ raising immutability errors) directly in Rust, and exposes free functions (uuid1..uuid8) that construct and return UUID instances. A separate compat submodule wraps these calls and rehydrates results into genuine stdlib uuid.UUID objects via object.__new__/object.__setattr__, trading a small amount of overhead for exact type compatibility. There is no persistence layer or external I/O — the entire surface is a synchronous, in-process ID-generation library, so the architecture’s only real complexity is the FFI boundary and keeping the Rust and Python type surfaces in sync.

Tech Stack Rust 2024 edition with pyo3 0.29 (extension-module feature) for the Python bindings, the uuid crate 1.24 with v1/v3/v4/v5/v6/v7/v8 feature flags enabled, rand 0.10 for randomness, and mac_address for node-ID resolution on non-wasm targets (with a wasm32 cfg branch that skips MAC lookup entirely, implying Pyodide/browser support is a design goal). The build is orchestrated by maturin with python-source = "python", producing wheels for CPython 3.10 through 3.14 (including the free-threaded 3.14t build) and PyPy 3.11. Documentation is built with mkdocs. CI covers Linux (x86_64/i686/aarch64/armv7/ppc64le via maturin-action cross builds and run-on-arch-action), and presumably equivalent macOS/Windows jobs, plus a dedicated codspeed.yml workflow for continuous benchmark tracking and a third-party.yml workflow (likely dependency/license auditing).

Code Quality The test suite (tests/test_uuid.py, test_stdlib_parity.py, test_compat/test_compat.py, test_benchmarks.py) totals roughly 570 lines and is organized around parity checks against the stdlib uuid module in addition to standalone correctness tests, plus a dedicated benchmark suite using pytest-codspeed that runs on every CI build via the linux/codspeed jobs. The lint CI job runs make lint (ruff, per the [tool.ruff.lint] config selecting E/W/F/I/C4/UP rule sets) and a docs build check, so both style and documentation are enforced pre-merge. Rust error handling is explicit and typed throughout (PyResult, typed PyValueError/PyTypeError/PyOSError conversions rather than panics), and the crate ships a .pyi stub file plus py.typed marker for static type checking on the Python side. No dedicated CONTRIBUTING file was found in the root, but the Makefile-driven make build/make test/make lint targets serve as the de facto contributor workflow.

What Makes It Unique The standout technical decision is treating UUID generation as a Rust-native, zero-copy problem rather than a thin ctypes/cffi wrapper — the UUID Python class itself lives entirely on the Rust side, so getters like .hex, .bytes, .time, .fields, and .version are computed in Rust with no Python-level bit-twiddling. The compat module’s dual-representation trick (fast Rust generation, stdlib-typed return value) is a pragmatic solution to a real interoperability problem — most “faster uuid” libraries either don’t offer this or require call-site changes. Its early support for UUIDv6/v7/v8 ahead of broad stdlib availability, continuous benchmark tracking via CodSpeed, and free-threaded/PyPy/wasm32 build targets show the project is tracking the leading edge of the CPython ecosystem rather than just wrapping an old library.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search