Skip to main content

Python binding for omq.rs (Rust libzmq port). Drop-in pyzmq replacement on the common path.

Project description

pyomq

Python binding for omq.rs, a Rust libzmq port. Drop-in pyzmq replacement on the common path.

Install

uv pip install pyomq
# Optional extras (built into the wheel via cargo features):
uv pip install 'pyomq[curve]'
uv pip install 'pyomq[blake3zmq,lz4,zstd]'
uv pip install 'pyomq[test]'   # adds pytest, pyzmq for the interop suite

Usage

import pyomq as zmq  # drop-in for `import zmq` from pyzmq

ctx = zmq.Context()
push = ctx.socket(zmq.PUSH)
push.connect("tcp://127.0.0.1:5555")
push.send(b"hello")
push.close()
ctx.term()

For asynchronous code:

import pyomq.asyncio as zmq_async

ctx = zmq_async.Context()
sock = ctx.socket(pyomq.PUSH)
await sock.connect("tcp://127.0.0.1:5555")
await sock.send(b"hello")
await sock.close()

Status

Sync and asyncio APIs both ship in this release. All 19 ZMTP socket types are wired:

  • Standard (RFC 28 + 47): PAIR, PUB, SUB, REQ, REP, DEALER, ROUTER, PULL, PUSH, XPUB, XSUB.
  • Draft: SERVER, CLIENT (RFC 41), RADIO, DISH (RFC 48), GATHER, SCATTER (RFC 49), PEER, CHANNEL (RFC 51).

Transports: tcp://, ipc://, inproc://, and udp:// (RADIO/DISH only). Optional features built into the wheel: curve, blake3zmq, lz4, zstd.

DISH groups: use socket.join(b"group") / socket.leave(b"group") to manage subscriptions; messages are sent as multipart [group, body].

Backend

pyomq is built on omq-compio (single-threaded io_uring on Linux). The runtime runs on a dedicated background thread; every Python call releases the GIL across the runtime trip. This is the only backend pyomq supports — the omq-tokio backend exists in the upstream Rust workspace for callers that need a multi-thread tokio integration, but pyomq's per-call overhead is shaped around compio's single-thread invariant.

Performance

PUSH/PULL throughput: Python bindings

Loopback PUSH/PULL throughput vs pyzmq, on a Linux 6.12 (Debian 13) VM on an Intel Mac Mini 2018 (i7-8700B, 3.2 GHz), Rust 1.95.0, default features:

Size inproc pyomq inproc pyzmq ratio tcp pyomq tcp pyzmq ratio
8 B 1.30 M/s 627 k/s 2.08× 1.36 M/s 565 k/s 2.41×
32 B 1.29 M/s 620 k/s 2.08× 1.36 M/s 576 k/s 2.37×
128 B 1.31 M/s 516 k/s 2.54× 1.29 M/s 496 k/s 2.61×
512 B 1.29 M/s 480 k/s 2.69× 1.21 M/s 461 k/s 2.62×
2 KiB 1.17 M/s 461 k/s 2.54× 908 k/s 342 k/s 2.65×
8 KiB 1.04 M/s 368 k/s 2.83× 349 k/s 102 k/s 3.41×
32 KiB 622 k/s 196 k/s 3.17× 116 k/s 46 k/s 2.50×
128 KiB 203 k/s 70 k/s 2.91× 32 k/s 24 k/s 1.32×

zmq.proxy() forwarding (128 B, TCP)

pyomq pyzmq ratio
PUSH/PULL msg/s 963 k/s 520 k/s 1.85×
REQ/REP rt/s 8,764/s 6,521/s 1.34×

pyomq's proxy() runs as a native Rust async loop on the compio thread — no Python per-message overhead. pyzmq's zmq.proxy() calls libzmq's C-level zmq_proxy. PUSH/PULL forwarding is throughput-bound and pyomq is ~1.9× faster. REQ/REP is latency-bound (4 TCP hops per round-trip) so both are similar.

Run scripts/update_perf.py (after maturin develop --release) to re-measure and update the tables above.

Compression transports

ØMQ adds two transparent compression transports on top of TCP: lz4+tcp:// (fast, low-latency) and zstd+tcp:// (higher ratio, better for large or structured payloads). Swap the scheme in your endpoint string and everything else stays the same:

push = ctx.socket(zmq.PUSH)
push.bind("lz4+tcp://127.0.0.1:5555")   # or zstd+tcp://

pull = ctx.socket(zmq.PULL)
pull.connect("lz4+tcp://127.0.0.1:5555")

Both peers must use a matching compression endpoint. Payloads below ~512 B are sent as-is (the codec detects that compression would expand them). For realistic JSON payloads at 2 KiB, lz4 yields ~3.8× and zstd ~4.5× on a bandwidth-limited link.

zstd+tcp:// also auto-trains a dictionary: it samples the first 1000 outbound messages (or 100 KiB of plaintext, whichever comes first), builds an 8 KiB dict, and ships it to the peer once. After that the compression threshold drops from 512 B to 64 B, so small structured messages start compressing too. lz4+tcp:// does not auto-train (LZ4 has no standard dict trainer).

Virtual throughput on bandwidth-limited links (JSON payloads, compio backend):

Compression throughput at 1 Gbps

Compression throughput at 100 Mbps

See BENCHMARKS.md for full tables including dict-trained ratios.

Develop

cd bindings/pyomq
uv venv && source .venv/bin/activate
uv pip install maturin pytest pyzmq
maturin develop --release
pytest -v

Project details


Download files

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

Source Distribution

pyomq-0.5.0.tar.gz (324.4 kB view details)

Uploaded Source

Built Distributions

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

pyomq-0.5.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.1 MB view details)

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

pyomq-0.5.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ ARM64

File details

Details for the file pyomq-0.5.0.tar.gz.

File metadata

  • Download URL: pyomq-0.5.0.tar.gz
  • Upload date:
  • Size: 324.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pyomq-0.5.0.tar.gz
Algorithm Hash digest
SHA256 f71eb2ba74a66a13d6c8890eed2798ee05a211eaa13b266f31afdb153c92e016
MD5 c87dadbd23de92f00fe15ad2ba1b297c
BLAKE2b-256 234b390f76faf17563d9bb0f194ebce516ad2117a7bfee0a4800e264eb4f946a

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyomq-0.5.0.tar.gz:

Publisher: release-pyomq.yml on paddor/omq.rs

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

File details

Details for the file pyomq-0.5.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyomq-0.5.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7169dec15ce3a6ffd704081848499d6ec0d5d3af1e1f6c3a4df3e4e0d2a289fc
MD5 4eb013699ada0134b0a78d3de87b41b0
BLAKE2b-256 e05bf22ee07be154ec92dd72f941d4d5949079c3ed4b95a19108b7e422ba99ce

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyomq-0.5.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release-pyomq.yml on paddor/omq.rs

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

File details

Details for the file pyomq-0.5.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for pyomq-0.5.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 13a4b03c842f5e5ec0b9fc514036c7afd561e49391d0a1c863b9f716e0775428
MD5 2b32ccabb840577d93ba008b2524201c
BLAKE2b-256 55b40f0bd781528202d642752515984a4320996f990e6277e40f20c2be0841a2

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyomq-0.5.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release-pyomq.yml on paddor/omq.rs

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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page