Introduction
ZeroMQ is not a message broker — it is a messaging library that gives you broker-less messaging patterns. Instead of deploying a server (like RabbitMQ or Kafka), you embed ZeroMQ directly in your application. It provides smart socket abstractions that handle connection management, buffering, routing, and reconnection automatically.
With over 11,000 GitHub stars (core C++ library), ZeroMQ is used when you need fast, lightweight messaging without the overhead of a full broker. It powers distributed systems at companies like Spotify, Samsung, and CERN.
What ZeroMQ Does
ZeroMQ provides socket types that implement common messaging patterns: REQ/REP (request-reply), PUB/SUB (publish-subscribe), PUSH/PULL (pipeline), and PAIR (exclusive). These sockets handle the complexity of async I/O, message framing, reconnection, and load balancing — you just send and receive messages.
Architecture Overview
[ZeroMQ Patterns]
[REQ/REP] — Request-Reply
Client sends request,
server sends reply.
Synchronous RPC-like.
[PUB/SUB] — Publish-Subscribe
Publisher broadcasts,
subscribers filter by topic.
[PUSH/PULL] — Pipeline
Push distributes work,
Pull collects results.
Fan-out / fan-in.
[DEALER/ROUTER] — Async Request-Reply
Async, multi-part messages,
custom routing.
[No Broker Required]
Peer-to-peer, embedded
in your application.
TCP, IPC, inproc, PGM.Self-Hosting & Configuration
# Pub/Sub pattern
# Publisher
import zmq, time
context = zmq.Context()
pub = context.socket(zmq.PUB)
pub.bind("tcp://*:5556")
while True:
pub.send_string("weather NYC 72F sunny")
pub.send_string("weather LA 85F clear")
pub.send_string("sports NBA Lakers won")
time.sleep(1)
# Subscriber (filter by topic)
context = zmq.Context()
sub = context.socket(zmq.SUB)
sub.connect("tcp://localhost:5556")
sub.setsockopt_string(zmq.SUBSCRIBE, "weather")
while True:
msg = sub.recv_string()
print(msg) # Only receives weather messages# Push/Pull pipeline (parallel processing)
# Ventilator (distributes work)
context = zmq.Context()
push = context.socket(zmq.PUSH)
push.bind("tcp://*:5557")
for i in range(100):
push.send_json({"task_id": i, "data": f"process_{i}"})
# Worker (multiple instances)
context = zmq.Context()
pull = context.socket(zmq.PULL)
pull.connect("tcp://localhost:5557")
push_result = context.socket(zmq.PUSH)
push_result.connect("tcp://localhost:5558")
while True:
task = pull.recv_json()
result = {"task_id": task["task_id"], "status": "done"}
push_result.send_json(result)Key Features
- Broker-less — no server to deploy, embedded in your application
- Multiple Patterns — REQ/REP, PUB/SUB, PUSH/PULL, DEALER/ROUTER
- High Performance — millions of messages per second
- Multiple Transports — TCP, IPC, in-process, multicast (PGM)
- Language Bindings — 40+ languages (Python, C, Go, Rust, Java, etc.)
- Auto-Reconnect — handles network failures and reconnection
- Message Framing — multi-part messages with zero-copy
- Scalability Patterns — built-in load balancing and fan-out
Comparison with Similar Tools
| Feature | ZeroMQ | RabbitMQ | NATS | gRPC | Kafka |
|---|---|---|---|---|---|
| Type | Library (no broker) | Message broker | Message broker | RPC framework | Event streaming |
| Deployment | Embedded | Server | Server | Embedded | Server cluster |
| Persistence | No | Yes | JetStream | No | Yes (log) |
| Patterns | Many (REQ/REP, PUB/SUB, PUSH/PULL) | Exchange-based | PUB/SUB, Queue | RPC | PUB/SUB |
| Speed | Very fast (no network hop to broker) | Fast | Very fast | Fast | High throughput |
| Best For | Low-latency P2P | Task queues | Microservices | API calls | Event streaming |
FAQ
Q: When should I use ZeroMQ instead of RabbitMQ or Kafka? A: ZeroMQ for ultra-low-latency peer-to-peer messaging where you do not need message persistence or a central broker. RabbitMQ for reliable task queues. Kafka for durable event streaming.
Q: Does ZeroMQ guarantee message delivery? A: ZeroMQ provides "at most once" delivery by default. For guaranteed delivery, implement acknowledgment patterns using REQ/REP or use a higher-level framework like Majordomo.
Q: Can ZeroMQ scale to many nodes? A: Yes. ZeroMQ patterns like PUSH/PULL and PUB/SUB scale naturally. ROUTER/DEALER enables complex multi-tier architectures. However, for very large systems, a broker (NATS, Kafka) may be easier to manage.
Q: Is ZeroMQ still maintained? A: Yes. The core library (libzmq) is actively maintained. The ecosystem includes CZMQ (high-level C API), PyZMQ (Python), and bindings for 40+ languages.
Sources
- GitHub: https://github.com/zeromq/libzmq
- Documentation: https://zeromq.org
- Guide: https://zguide.zeromq.org
- Created by iMatix (Pieter Hintjens)
- License: MPL-2.0