Native CPython bindings · IPC and UDP · optional embedded driver

pyaeron

Bring the Aeron C client into Python with a focused native extension. Publish and consume messages over shared memory or UDP while working directly with familiar Python buffers.

Apache-2.0 CPython 3.12–3.15 embedded driver available IPC and UDP

pyaeron · Python 375 ns IPC p50 · 32-byte RPC on Apple M4 Max.
pyaeron · Python 66.3 µs Localhost UDP p50 · 32-byte RPC on Apple M4 Max.

Aeron’s core model, expressed cleanly in Python.

The API keeps Aeron’s publications, subscriptions, channels, and streams while working naturally with Python buffers, callbacks, exceptions, and context managers.

01 / PUBLISH

Publish without reshaping your data.

Pass bytes or another supported buffer to offer(). Choose a regular publication when multiple threads may publish, or an exclusive publication for a single publisher.

Input
bytes, strings, and contiguous buffers
Flow control
explicit back-pressure feedback
Concurrency
regular or exclusive publication
Transport
shared memory or UDP
02 / SUBSCRIBE

Poll on your own schedule.

Subscriptions deliver available fragments to a Python handler without blocking. Poll every session together, or work with one Aeron Image at a time.

Polling
non-blocking
Fragments
assembled or delivered as-is
Sessions
combined or selected by Image
Idle strategy
spin, yield, sleep, or back off

Publish to a log. Poll at your own pace.

A publication and subscription connect when their channel and stream ID match. Use aeron:ipc for same-host shared memory or an Aeron UDP channel to communicate across the network.

01 / PUBLISHER

Offer a payload

Pass a supported buffer to offer(). pyaeron passes its contents directly to the C client without creating an intermediate Python bytes object.

02 / MEDIA DRIVER

Move it through Aeron

Aeron coordinates shared-memory logs, flow control, and network transport through an embedded or separately managed media driver.

03 / SUBSCRIBER

Handle available data

poll() delivers available fragments to a Python handler. Copy a payload only when it needs to outlive the callback.

What zero-copy means

pyaeron avoids an extra copy at the Python-to-C boundary. Aeron still writes the message into its term log, and direct buffer inputs must be contiguous.

What an Image is

An Aeron Image represents one publication session as seen by a subscription. Poll the subscription for every session, or one image when you need session-level control.

Move bytes between Python and Aeron with less overhead.

Accepted inputs

payloadhandling
bytesdirect
bytearraydirect
C-contiguous memoryviewdirect
ASCII strdirect
non-ASCII strencoded as UTF-8
other contiguous buffersdirect through the buffer protocol

Threading

pyaeron releases the GIL while it waits for connections or driver responses, allowing other Python threads to run. Short, non-blocking offer() and poll() calls retain it.

For sustained polling, give each loop a deliberate idle strategy. If several loops must remain active, separate processes keep them from competing for the GIL.

From shared memory to 100 GbE.

These one-at-a-time request-and-response measurements show round-trip latency, not peak throughput. Each run sends a 32-byte message and waits for its response before sending the next.

transport environment p50 mean round trips/s
IPC same host 0.16 µs 0.22 µs 3.7M
localhost UDP same host 17 µs 17 µs 58k
100 GbE ConnectX-5 + VMA two hosts · user space 5.9 µs 6.0 µs 165k
10 GbE X540 two hosts 158 µs 167 µs 6.0k

Measured with the Aeron C client, exclusive publications, and a dedicated media driver. Driver threads were pinned to dedicated cores, with the benchmark process and memory kept on the NIC's NUMA node. The 100 GbE path uses NVIDIA VMA kernel bypass with verified RX and TX offload; the other UDP paths use the kernel network stack. These figures establish the underlying transport baseline; Python is not part of the measured path.

Install. Send your first message.

With CPython 3.12–3.15 on macOS Apple silicon or x86-64 Linux, pip installs a prebuilt wheel. The embedded media driver makes this first program self-contained—there is no Aeron service to configure.

Install from PyPI
$ python -m pip install pyaeron
hello.py
import pyaeron

received = []

with pyaeron.Aeron(embedded=True) as aeron:
    sub = aeron.add_subscription(pyaeron.IPC_CHANNEL, 1001)
    pub = aeron.add_publication(pyaeron.IPC_CHANNEL, 1001)
    pub.await_connected(timeout=5)
    sub.await_connected(timeout=5)

    while pub.offer(b"Hello, Aeron!") is not True:
        aeron.idle.idle()

    while not received:
        work = sub.poll(lambda buf, _: received.append(bytes(buf)))
        aeron.idle.idle(work)

print(received[0].decode())
Run it
$ python hello.py
Hello, Aeron!