Skip to content

ZeroMQ

Brokerless messaging patterns — sockets that speak pub/sub, request/reply and push/pull.

Networking & ConcurrencyNetworkingC++

What it is

ZeroMQ is a high-performance asynchronous messaging library for building distributed and concurrent applications. It provides sockets that carry atomic messages across processes, machines, or threads with patterns like pub-sub, request-reply, and pipeline.

ZeroMQ provides socket types (`REQ`, `REP`, `PUB`, `SUB`, `PUSH`, `PULL`) that can be connected in messaging topologies. It supports asynchronous, non-blocking communication, high throughput, and minimal latency.

Licence
MPL 2.0
Watch for
Messages are held in memory — a crash loses anything in flight

When to use it

The question documentation cannot answer for you — because it cannot recommend something else.

Reach for it when

  • You want messaging patterns without operating a broker
  • Low-latency inter-process or inter-thread communication

Look elsewhere when

  • You need message durability, replay or delivery guarantees — that requires a real broker
  • The team expects a managed queue with an operations dashboard

Installation

sudo apt install libzmq3-dev

Getting started

The smallest useful thing you can do with it, and what each part means.

Hello World server (reply)
#include <zmq.hpp>
#include <string>
#include <iostream>

int main() {
    zmq::context_t context(1);
    zmq::socket_t socket(context, ZMQ_REP);
    socket.bind("tcp://*:5555");

    while (true) {
        zmq::message_t request;
        socket.recv(request);
        std::cout << "Received: " << request.to_string() << std::endl;

        zmq::message_t reply("World", 5);
        socket.send(reply, zmq::send_flags::none);
    }
    return 0;
}
A simple ZeroMQ server using the request-reply pattern.
Hello World client (request)
zmq::context_t context(1);
zmq::socket_t socket(context, ZMQ_REQ);
socket.connect("tcp://localhost:5555");

zmq::message_t request("Hello", 5);
socket.send(request, zmq::send_flags::none);

zmq::message_t reply;
socket.recv(reply);
std::cout << "Received reply: " << reply.to_string() << std::endl;
A simple client sending requests and receiving replies.

Advanced usage

Where the library earns its place over a simpler alternative.

Publish-Subscribe
// Publisher
zmq::socket_t pub(context, ZMQ_PUB);
pub.bind("tcp://*:5556");
zmq::message_t msg("Update 1", 8);
pub.send(msg, zmq::send_flags::none);

// Subscriber
zmq::socket_t sub(context, ZMQ_SUB);
sub.connect("tcp://localhost:5556");
sub.set(zmq::sockopt::subscribe, "");
Implements a pub-sub model where one publisher sends updates to many subscribers.
Pipeline (Push-Pull)
zmq::socket_t push(context, ZMQ_PUSH);
push.bind("tcp://*:5557");
zmq::socket_t pull(context, ZMQ_PULL);
pull.connect("tcp://localhost:5557");
Implements a task distribution model where tasks are pushed by producers and pulled by workers.
Non-blocking receive
zmq::message_t msg;
bool received = socket.recv(msg, zmq::recv_flags::dontwait);
if (received) {
    std::cout << "Got message: " << msg.to_string() << std::endl;
}
Demonstrates asynchronous message receiving without blocking.
Polling multiple sockets
zmq::pollitem_t items[] = {{socket1, 0, ZMQ_POLLIN, 0}, {socket2, 0, ZMQ_POLLIN, 0}};
zmq::poll(items, 2, 1000);
Polls multiple sockets simultaneously with a timeout.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

zmq::error_t: Connection refused
Ensure the server socket is bound and listening before connecting clients.
zmq::error_t: Operation would block
Occurs with non-blocking sockets. Check readiness with polling before sending/receiving.
Dropped messages in PUB-SUB
Subscribers only receive messages after they have subscribed. Consider buffering or queueing if needed.

Best practices

  • Choose the right messaging pattern (`REQ-REP`, `PUB-SUB`, `PUSH-PULL`) for your use case.
  • Use non-blocking sockets or polling to avoid deadlocks.
  • Always close sockets and terminate the context to free resources.
  • Handle network errors gracefully; ZeroMQ does not guarantee message delivery by default.
  • For secure messaging, combine with encryption frameworks like CurveZMQ.

Alternatives

Comparable options, and the reason you would pick one over the other.

Background

Why it exists, and what it was reacting to.

ZeroMQ (also known as ØMQ) was created in 2007 by iMatix Corporation to provide a lightweight messaging layer that is faster and more flexible than traditional message brokers like AMQP or JMS. Unlike typical brokers, ZeroMQ is brokerless—applications communicate directly via sockets while still supporting rich messaging patterns. It has become popular in finance, IoT, distributed systems, and high-performance computing.