Skip to main content

hyperuuid

Python 3.14 finally added uuid.uuid7() to stdlib, with a real monotonic counter — genuinely well done. If you're stuck on 3.9-3.13 like most production code still is, stdlib has no v6/v7 at all, and this package gives you both today without waiting for a runtime upgrade — and on any version, the native backend below outruns stdlib outright.

RFC 9562 UUID v4 (random), v5 (deterministic), v6 and v7 (time-sortable) generation. A native extension built with PyO3 — the Rust core linked directly into the CPython extension module, no dlopen, no C-ABI hop, no ctypes marshalling, no runtime bridge.

Ships as real platform-specific wheels — linux/macOS/Windows, x64/arm64, six in total, one abi3 build covering every supported CPython 3.9+ — so pip install hyperuuid lands at native speed with nothing to compile, the same way numpy or cryptography does.

Not yet covered: free-threaded (no-GIL) CPython (3.13t/3.14t). pip install hyperuuid currently fails outright there (No matching distribution found) — an abi3 wheel is ignored by a free-threaded interpreter (it's a genuinely separate ABI, not a compatibility flag), so closing this gap means building and shipping additional version-specific cp313t/cp314t wheels alongside the existing six, not just a build-flag change. PyO3 itself has supported free-threading (opt-in, gil_used = false) since 0.23; the cleaner long-term fix — PEP 803's abi3t stable ABI, one build covering both GIL and no-GIL — needs Python 3.15+, not yet released. Revisiting once that lands or free-threaded adoption justifies the extra wheel legs.

import uuid
import hyperuuid

hyperuuid.new_v4()
hyperuuid.new_v5(uuid.NAMESPACE_DNS, "example.com")
hyperuuid.new_v6()
id4 = hyperuuid.new_v7()

hyperuuid.v7_timestamp(id4) # recover the embedded UTC datetime.datetime
hyperuuid.get_timestamp(id4) # None instead of assuming id4 is v6/v7
hyperuuid.v7_to_sql_order(id4) # byte order SQL Server's uniqueidentifier needs to sort by creation order

# One native call, one random-bytes fetch, one counter reservation for the whole batch:
batch = hyperuuid.new_v7_batch(1000)

Returns stdlib uuid.UUID objects — built through the fastuuid-style fast path (UUID.__new__ plus object.__setattr__ of the int/is_safe slots), since UUID.__init__'s own validation costs more than the entire native call; the test suite pins constructor indistinguishability so this can't silently drift from a real UUID(bytes=...) construction. For v5's namespace argument, use the RFC 9562 Section 6.6 well-known namespaces already in the standard library — uuid.NAMESPACE_DNS, NAMESPACE_URL, NAMESPACE_OID, NAMESPACE_X500 — no need for this package to redefine them. hyperuuid.NIL/MAX are the RFC 9562 §5.9/§5.10 special-value UUIDs. hyperuuid.v7_timestamp(id) recovers the embedded UTC datetime.datetime from a version 7 UUID (raises OverflowError past year 9999 — the RFC's 48-bit field holds values up to year 10889, but datetime.datetime cannot); hyperuuid.v6_timestamp(id) does the same for version 6, and can never raise that way — v6's 60-bit tick count, offset from the 1582 UUID epoch, tops out around the year 5236. new_v6/new_v7 also accept a datetime.datetime directly in place of a raw millisecond count. get_timestamp(id) is the version-agnostic counterpart to v6_timestamp/v7_timestamp — it checks id.version itself and returns None for anything but a genuine v6/v7 UUID, instead of assuming the caller already knows. hyperuuid.new_v6_batch(count)/ new_v7_batch(count) generate count UUIDs sharing one timestamp capture and one native call, instead of count of each. hyperuuid.v7_to_sql_order(id)/ v7_from_sql_order(id) convert a version 7 UUID to and from the byte order SQL Server's uniqueidentifier needs on the wire to sort by creation order — computed once in the native Rust core rather than reimplemented in Python, and verified there (and independently against the real System.Data.SqlTypes.SqlGuid comparator in the C# binding's test suite). v6_to_sql_order(id)/ v6_from_sql_order(id) do the same for version 6, though same-millisecond v6 UUIDs aren't guaranteed to sort correctly afterward — v6 has no counter, so clock_seq/node (not the timestamp) decide ties, the same pre-existing RFC 9562 v6 limitation plain order already has.

Why not stdlib uuid?

This is the one binding where the honest answer genuinely depends on which Python you're running — this package supports 3.9+, and stdlib's own v6/v7 story changed dramatically partway through that range:

  • Python 3.9-3.13: stdlib has uuid1/uuid3/uuid4/uuid5 — no v6, no v7, at all. This package is the only way to get either without a third-party dependency, and the native backend outruns stdlib's v4/v5 on top of that.
  • Python 3.14+: stdlib added uuid.uuid6()/uuid7()/uuid8(), and uuid7() genuinely implements RFC 9562 §6.2's monotonic counter (42 bits of it) — this isn't a naive random-bits implementation, it's a real, well-built addition, and it's what the benchmarks below measure against. This package still wins across the board there — see Benchmarks — plus:
    1. Cross-language consistency. The same Rust core mints v5 namespace UUIDs for Go, C#, Ruby, and every other binding in this repo — verified in CI to match stdlib's own uuid.uuid5 byte-for-byte. If your stack isn't Python-only, or you need every service minting IDs from the literal same engine rather than N independent (if individually correct) implementations, that's not something stdlib can offer regardless of version.
    2. Batch generation. new_v7_batch(count) shares one timestamp capture, one random-bytes fetch, and one counter reservation across the whole batch — stdlib's uuid7() has no bulk-generation entry point, so a loop of individual calls is the only option there.
    3. One behavior across your whole supported range. If your package needs to run on 3.9 and 3.14, this avoids sys.version_info-gated code paths for v6/v7 support.

Benchmarks

Measured with pyperf (linux-arm64, CPython 3.14.5, python bench_uuid.py --fast; see bench_uuid.py). Linking the core directly into the extension module — no ctypes boundary to cross — turns every one of these into a win against stdlib's own C-accelerated implementations:

Call hyperuuid vs. closest stdlib equivalent
hyperuuid.new_v4() 647 ns uuid.uuid4(): 1.03 µs — 1.6x faster
hyperuuid.new_v5(...) 811 ns uuid.uuid5(...): 2.0 µs — 2.5x faster
hyperuuid.new_v6(...) ~650 ns uuid.uuid6() (3.14+): 2.85 µs — 4.2x faster
hyperuuid.new_v7(...) ~685 ns uuid.uuid7() (3.14+): 2.69 µs — 4.2x faster

Batch generation amortizes per-call cost, though it's now construction-bound (1.27x over the loop) rather than FFI-bound — the next tuning target:

Mean vs. individual calls
new_v6_batch(1000) 1.03 ms ± 0.06 ms vs. 1000x new_v6(): 2.25 ms ± 0.20 ms — 2.2x
new_v7_batch(1000) 1.05 ms ± 0.10 ms vs. 1000x new_v7(): 2.21 ms ± 0.18 ms — 2.1x

Timestamp extraction vs. stdlib's .time property

CPython 3.14's uuid.UUID.time has real version-aware extraction logic of its own (branches on version, computes the right thing for v6/v7, not just a v1-only stub), so this is a genuine head-to-head — each call measured against a UUID generated once outside the timed loop, so only the extraction itself is timed:

Call hyperuuid vs. stdlib .time
hyperuuid.v6_timestamp(...) ~248 ns UUID.time (v6): ~665 ns — 2.7x faster
hyperuuid.v7_timestamp(...) ~248 ns UUID.time (v7): ~665 ns — 2.7x faster

Worth noting: stdlib's .time for v6 returns raw Gregorian-epoch 100ns ticks, not Unix milliseconds like hyperuuid.v6_timestamp — different units if you actually need the value, but a fair timing comparison of "the cost of pulling the embedded time out" either way.

Reproduce: maturin develop --release --manifest-path native/Cargo.toml (from python/) to build the release extension — pip install -e ".[bench]" alone builds debug by default and will understate every number above — then pip install pyperf and python bench_uuid.py --fast -o results.json.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

hyperuuid-0.1.0-cp39-abi3-win_arm64.whl (133.7 kB view details)

Uploaded CPython 3.9+Windows ARM64

hyperuuid-0.1.0-cp39-abi3-win_amd64.whl (136.8 kB view details)

Uploaded CPython 3.9+Windows x86-64

hyperuuid-0.1.0-cp39-abi3-manylinux_2_28_x86_64.whl (278.6 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.28+ x86-64

hyperuuid-0.1.0-cp39-abi3-manylinux_2_28_aarch64.whl (273.0 kB view details)

Uploaded CPython 3.9+manylinux: glibc 2.28+ ARM64

hyperuuid-0.1.0-cp39-abi3-macosx_11_0_arm64.whl (238.0 kB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

hyperuuid-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl (244.1 kB view details)

Uploaded CPython 3.9+macOS 10.12+ x86-64

File details

Details for the file hyperuuid-0.1.0-cp39-abi3-win_arm64.whl.

File metadata

  • Download URL: hyperuuid-0.1.0-cp39-abi3-win_arm64.whl
  • Upload date:
  • Size: 133.7 kB
  • Tags: CPython 3.9+, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for hyperuuid-0.1.0-cp39-abi3-win_arm64.whl
Algorithm Hash digest
SHA256 3469d76bcbc8d05650c24e9bab7d63f6377978871b325fb17cad4959e0778aed
MD5 c9a4df95c776b9bce1a8d255db652eb3
BLAKE2b-256 b50bb5b3c5ec6cf3ee3ded3580547ddb2ec9ab06eeec0ba3c59f26e0a6c9b5eb

See more details on using hashes here.

Provenance

The following attestation bundles were made for hyperuuid-0.1.0-cp39-abi3-win_arm64.whl:

Publisher: release.yml on SkunkWerkx/HyperUuid

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hyperuuid-0.1.0-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: hyperuuid-0.1.0-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 136.8 kB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for hyperuuid-0.1.0-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 47a334a8efac74ed7a56f014739819c2e22d7bc190c463c992ce4e331ce4ff44
MD5 e2209489d96908a906dab9a2d24b7199
BLAKE2b-256 d62365e0e6eff00827ae9de52f911c635bc810f20989463dd2b719669fc7c435

See more details on using hashes here.

Provenance

The following attestation bundles were made for hyperuuid-0.1.0-cp39-abi3-win_amd64.whl:

Publisher: release.yml on SkunkWerkx/HyperUuid

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hyperuuid-0.1.0-cp39-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for hyperuuid-0.1.0-cp39-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 557ccaf64d0f5e165607ad9ffa8e849660c5f558211beba206b6fb2b721253bd
MD5 55724f06cd1fe5cdb4cfa656669aae3b
BLAKE2b-256 efce17f9e22abaed69e8fc966a2e68110c787f57bb5c16b349bb9d24913679f7

See more details on using hashes here.

Provenance

The following attestation bundles were made for hyperuuid-0.1.0-cp39-abi3-manylinux_2_28_x86_64.whl:

Publisher: release.yml on SkunkWerkx/HyperUuid

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hyperuuid-0.1.0-cp39-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for hyperuuid-0.1.0-cp39-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 951494129d006b152f3baf0968ca49071865fee1da0fac9f93ed720d3a1407f6
MD5 2b82f63408cffb73817b620a785d0ddc
BLAKE2b-256 5218d7cd6273b4e7eee3d4bd499c2230c40031c857e772eede9eefc2c1bde348

See more details on using hashes here.

Provenance

The following attestation bundles were made for hyperuuid-0.1.0-cp39-abi3-manylinux_2_28_aarch64.whl:

Publisher: release.yml on SkunkWerkx/HyperUuid

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hyperuuid-0.1.0-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for hyperuuid-0.1.0-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2046495b80109b11eac5248808722f77b06ab80bd912dc8e6606f9ba94dea795
MD5 53ec831637f641baa65a992000e22820
BLAKE2b-256 b9e9b1496284c4a526ae90bc119e681d604003ac7123763ac40352c4fc7a7897

See more details on using hashes here.

Provenance

The following attestation bundles were made for hyperuuid-0.1.0-cp39-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on SkunkWerkx/HyperUuid

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hyperuuid-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for hyperuuid-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 6e9077cba6165b0d8f16601612398b40ff9c7b333e5bb203232a857cd8f0e50a
MD5 2fd6ef5e8e5b0da76901f1b7d6807c08
BLAKE2b-256 16a2bae3e5492add3dc6b0025d1bae9393e42239dcfab3dec673ff591588fee9

See more details on using hashes here.

Provenance

The following attestation bundles were made for hyperuuid-0.1.0-cp39-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on SkunkWerkx/HyperUuid

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0 This release

6 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page