Install & Compatibility
Where this runs
tested against v27.2.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.078s · 25.5MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 2.0s · import 0.066s · 22MB
22MB installed
● package 22MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
zmq
✓ import zmq
✗ import pyzmq
The primary module to import for PyZMQ functionality is `zmq`, not `pyzmq`. The `pyzmq` package is installed, but its main API is exposed via the `zmq` module.
Context
✓ import zmq
context = zmq.Context()
The `Context` manages the ZeroMQ runtime and should be created once per application or thread.
Socket
✓ import zmq
socket = context.socket(zmq.REQ)
Sockets are created from a `Context` and are the primary means of sending and receiving messages. `zmq.REQ`, `zmq.REP`, `zmq.PUB`, `zmq.SUB` etc. define the socket type.
This quickstart demonstrates how to initialize PyZMQ, create a context and a PUSH socket, bind it to a local address, and send a simple string message. It also shows proper cleanup of sockets and context.
import zmq
# Get PyZMQ and underlying ZeroMQ library versions
print(f"PyZMQ version: {zmq.__version__}")
print(f"ZeroMQ library version: {zmq.zmq_version()}\n")
# Create a ZeroMQ context, which manages connections and sockets
context = zmq.Context()
# Create a PUSH socket (a simple one-way message sender)
socket = context.socket(zmq.PUSH)
try:
# Bind the socket to a random ephemeral port on localhost
# In a real application, you'd bind/connect to a known address
port = socket.bind_to_random_port("tcp://127.0.0.1")
print(f"PUSH socket bound to tcp://127.0.0.1:{port}")
# Send a message
message = "Hello from PyZMQ!"
socket.send_string(message)
print(f"Sent message: '{message}'")
except zmq.ZMQError as e:
print(f"ZeroMQ Error occurred: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
finally:
# Always close sockets and terminate the context to release resources
if socket:
socket.close()
print("Socket closed.")
if context:
context.term()
print("Context terminated.")
Debug
Known issues
gotchaThe PyPI package name is `pyzmq`, but the primary Python module to import is `zmq`. Attempting `import pyzmq` will not expose the core ZeroMQ API (though `pyzmq` itself is a valid, but less common, module).fixAlways use `import zmq` to access PyZMQ's functionality.
affects: All versions
gotchaBy default, `socket.recv()` and `socket.send()` are blocking operations. If no message is available or the send buffer is full, your application can hang indefinitely.fixUse `socket.poll()` to check for activity, or pass `zmq.NOBLOCK` flag to `send()`/`recv()`. When using `NOBLOCK`, be prepared to handle `zmq.Again` (EAGAIN) exceptions when an operation would block.
affects: All versions
gotchaIt is crucial to properly close all sockets with `socket.close()` and terminate the ZeroMQ context with `context.term()` to release system resources. Failing to do so can lead to resource leaks, hanging processes, or prevent proper application shutdown.fixImplement proper lifecycle management, typically using `try...finally` blocks or context managers, to ensure sockets are closed and the context is terminated.
affects: All versions
breakingThe integration with `asyncio` underwent significant changes around PyZMQ version 17.x. Older patterns of integrating with asyncio might no longer work or behave differently, particularly regarding event loop management and `asyncio.set_event_loop()`.fixFor asyncio, always use the `zmq.asyncio` module and its `Context`. Refer to the official PyZMQ documentation for the correct modern `asyncio` integration patterns.
affects: Before 17.x, especially when upgrading to 17.x or later.
gotchaZeroMQ messages are 'framed' by the library, but sending multiple distinct parts requires using `socket.send_multipart()` and `socket.recv_multipart()`. Concatenating strings and sending with `send_string()` will be treated as a single message part.fixWhen needing to send multiple logical parts in a single ZeroMQ message, use `socket.send_multipart(list_of_bytes_or_strings)` and `socket.recv_multipart()`.
affects: All versions
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'zmq'
The PyZMQ library, which provides the 'zmq' module, is not installed in the current Python environment.
zmq.error.ZMQError: Address already in use
The requested port for binding a ZeroMQ socket is already occupied by another process or a previously unclosed socket.
fixEnsure all previous sockets are properly closed and unbound, or choose a different available port for binding.
zmq.error.ZMQError: Operation cannot be accomplished in current state
An unsupported operation was attempted on a ZeroMQ socket type (e.g., trying to send on a SUB socket or recv on a PUB socket).
fixVerify the socket type (e.g., zmq.REQ, zmq.REP, zmq.PUB, zmq.SUB) matches the intended messaging pattern and the specific operation being performed.
zmq.error.Again
A non-blocking socket operation (e.g., recv with zmq.NOBLOCK) was called when no data was immediately available, or a send buffer was full.
fixHandle the zmq.Again exception by retrying the operation later, using socket.poll() to wait for events, or switching to blocking operations if appropriate.
Upgrade
Version history
27.2.0latest on PyPI · released Aug 20, 2026
Audit
Dependencies
No dependency data recorded yet.