Connect threads, processes, hosts, and languages without a broker.
See the codeZeroMQ messaging, built in Rust.
Connect threads, processes, hosts, and languages without a broker. Your application sends messages, OMQ handles the network. Queues all the way!
Same socket types, same connect/bind/send/recv:
cargo add omq-tokio --rename omq
cargo add tokio --features macros,rt-multi-thread
use omq::{Context, Message, Options, Result, SocketType};
#[tokio::main]
async fn main() -> Result<()> {
let ctx = Context::new();
let pull = ctx.socket(SocketType::Pull, Options::default());
let endpoint = pull.bind("tcp://127.0.0.1:0").await?;
let push = ctx.socket(SocketType::Push, Options::default());
push.connect(endpoint).await?;
push.send(Message::single("hello")).await?;
let msg = pull.recv().await?;
assert_eq!(&msg[0], b"hello");
Ok(())
}
The application can await bind, connect, send, and recv on any runtime
like Tokio or Compio. OMQ handles the network on its own background IO threads.
Port 0 selects a free TCP port, returned by bind().
More examples in examples/zguide/, a port of the ZeroMQ Guide patterns to OMQ.
Full comparison charts | Other protocol comparisons
OMQ normally runs transport work on dedicated background IO threads, separate from application threads. Embedded and exclusive APIs are also available:
| API | IO placement |
|---|---|
Context::new().socket(...) | OMQ-owned background IO threads, async API |
Context::new().blocking_socket(...) | OMQ-owned background IO threads, synchronous API |
Context::current().socket(...) | Existing tokio runtime |
omq_tokio::exclusive::Socket::{connect, bind}(...) | Caller task, one TCP peer, no socket driver task |
Owned contexts support independent aggregate ingress/egress byte limits, configured before the first socket; exhaustion applies backpressure. Limits count transport bytes after compression and each fan-out copy; IPC, inproc, and SHM are excluded.
let ctx = omq::Context::new();
ctx.set_network_rate_limits(omq::NetworkRateLimits {
ingress: None,
egress: Some(omq::ByteRateLimit::new(10_000_000, 100_000)),
})?;
The default build includes the NULL mechanism and TCP / IPC / inproc / UDP, plus SHM on Linux. It needs no libzmq, libsodium, or C compiler. Optional features:
| Feature | Adds |
|---|---|
plain | PLAIN username/password authentication (RFC 24) |
curve | CURVE authentication and encryption (RFC 26) |
lz4 | lz4+tcp:// compression (RFC) |
zstd | Experimental zstd+tcp:// compression |
ws | WebSocket (ws://) and verified TLS (wss://) |
quic | TLS-encrypted QUIC (quic://): overview, example |
dart | Reliable ordered UDP (dart://) for low latency: overview, RFC |
Five Cargo workspace crates. The protocol core and tokio backend forbid unsafe Rust. SHM transport and native interfaces isolate unsafe operations.
| Crate | What it does |
|---|---|
omq-proto | Sans-I/O ZMTP 3.x: codec, messages, mechanisms, subscriptions |
omq-tokio | Tokio backend for Linux, macOS, and Windows |
omq-shm | Linux shared-memory transport |
omq-libzmq | libzmq-compatible C interface (libomq_zmq dynamic/static library) |
omq-bench | Benchmark runner and SVG chart generator |
Language bindings:
| Language | Binding |
|---|---|
| C/C++ | omq-libzmq: libzmq-compatible C API |
| Python | pyomq: synchronous and asyncio APIs |
| Ruby | omq-rs: scheduler-aware synchronous API |
| Go | OMQ.go: goroutine-safe API |
| Java | OMQ.java: synchronous and async APIs |
| Node.js | OMQ.node: native addon |
| .NET | OMQ.Net: managed wrapper |
| Lua | OMQ.lua: native module |
| Erlang, Elixir, Gleam | OMQ.beam: NIF and wrappers |
| Zig | OMQ.zig: C API wrapper |
| Crystal | omq-binding.cr: native binding |
x86_64, aarch64, i686-unknown-linux-gnu, armv7-unknown-linux-gnueabihf)Linux is the primary development and benchmarking platform.
See CONTRIBUTING.md for guidelines and DEVELOPMENT.md for build and test commands, and RUNNING_BENCHMARKS.md for benchmarks.
This project was built with significant LLM assistance throughout: architecture, implementation, tests, benchmark infrastructure, and docs. It's an experiment in what LLM-assisted development can and can't do. The design decisions and direction are mine.
ISC.
1,431 followers · starred Sep 2026
827 followers · starred Sep 2026
69 followers · starred Jul 2026
84 followers · starred Jul 2026
Connect threads, processes, hosts, and languages without a broker.
See the codeZeroMQ messaging, built in Rust.
Connect threads, processes, hosts, and languages without a broker. Your application sends messages, OMQ handles the network. Queues all the way!
Same socket types, same connect/bind/send/recv:
cargo add omq-tokio --rename omq
cargo add tokio --features macros,rt-multi-thread
use omq::{Context, Message, Options, Result, SocketType};
#[tokio::main]
async fn main() -> Result<()> {
let ctx = Context::new();
let pull = ctx.socket(SocketType::Pull, Options::default());
let endpoint = pull.bind("tcp://127.0.0.1:0").await?;
let push = ctx.socket(SocketType::Push, Options::default());
push.connect(endpoint).await?;
push.send(Message::single("hello")).await?;
let msg = pull.recv().await?;
assert_eq!(&msg[0], b"hello");
Ok(())
}
The application can await bind, connect, send, and recv on any runtime
like Tokio or Compio. OMQ handles the network on its own background IO threads.
Port 0 selects a free TCP port, returned by bind().
More examples in examples/zguide/, a port of the ZeroMQ Guide patterns to OMQ.
Full comparison charts | Other protocol comparisons
OMQ normally runs transport work on dedicated background IO threads, separate from application threads. Embedded and exclusive APIs are also available:
| API | IO placement |
|---|---|
Context::new().socket(...) | OMQ-owned background IO threads, async API |
Context::new().blocking_socket(...) | OMQ-owned background IO threads, synchronous API |
Context::current().socket(...) | Existing tokio runtime |
omq_tokio::exclusive::Socket::{connect, bind}(...) | Caller task, one TCP peer, no socket driver task |
Owned contexts support independent aggregate ingress/egress byte limits, configured before the first socket; exhaustion applies backpressure. Limits count transport bytes after compression and each fan-out copy; IPC, inproc, and SHM are excluded.
let ctx = omq::Context::new();
ctx.set_network_rate_limits(omq::NetworkRateLimits {
ingress: None,
egress: Some(omq::ByteRateLimit::new(10_000_000, 100_000)),
})?;
The default build includes the NULL mechanism and TCP / IPC / inproc / UDP, plus SHM on Linux. It needs no libzmq, libsodium, or C compiler. Optional features:
| Feature | Adds |
|---|---|
plain | PLAIN username/password authentication (RFC 24) |
curve | CURVE authentication and encryption (RFC 26) |
lz4 | lz4+tcp:// compression (RFC) |
zstd | Experimental zstd+tcp:// compression |
ws | WebSocket (ws://) and verified TLS (wss://) |
quic | TLS-encrypted QUIC (quic://): overview, example |
dart | Reliable ordered UDP (dart://) for low latency: overview, RFC |
Five Cargo workspace crates. The protocol core and tokio backend forbid unsafe Rust. SHM transport and native interfaces isolate unsafe operations.
| Crate | What it does |
|---|---|
omq-proto | Sans-I/O ZMTP 3.x: codec, messages, mechanisms, subscriptions |
omq-tokio | Tokio backend for Linux, macOS, and Windows |
omq-shm | Linux shared-memory transport |
omq-libzmq | libzmq-compatible C interface (libomq_zmq dynamic/static library) |
omq-bench | Benchmark runner and SVG chart generator |
Language bindings:
| Language | Binding |
|---|---|
| C/C++ | omq-libzmq: libzmq-compatible C API |
| Python | pyomq: synchronous and asyncio APIs |
| Ruby | omq-rs: scheduler-aware synchronous API |
| Go | OMQ.go: goroutine-safe API |
| Java | OMQ.java: synchronous and async APIs |
| Node.js | OMQ.node: native addon |
| .NET | OMQ.Net: managed wrapper |
| Lua | OMQ.lua: native module |
| Erlang, Elixir, Gleam | OMQ.beam: NIF and wrappers |
| Zig | OMQ.zig: C API wrapper |
| Crystal | omq-binding.cr: native binding |
x86_64, aarch64, i686-unknown-linux-gnu, armv7-unknown-linux-gnueabihf)Linux is the primary development and benchmarking platform.
See CONTRIBUTING.md for guidelines and DEVELOPMENT.md for build and test commands, and RUNNING_BENCHMARKS.md for benchmarks.
This project was built with significant LLM assistance throughout: architecture, implementation, tests, benchmark infrastructure, and docs. It's an experiment in what LLM-assisted development can and can't do. The design decisions and direction are mine.
ISC.
1,431 followers · starred Sep 2026
827 followers · starred Sep 2026
69 followers · starred Jul 2026
84 followers · starred Jul 2026