Skip to main content

tachyon-ipc (Python)

Python bindings for Tachyon, a bare-metal lock-free IPC. SPSC ring buffer over POSIX shared memory with sub-100 ns p50 RTT.

The C++ core is exposed via a CPython extension (_tachyon.so). No subprocess, no serialization, no broker.


Requirements

Component Minimum
OS Linux 5.10+ (primary), macOS 13+ (tier-2)
Python 3.11+
Compiler GCC 14+ or Clang 17+ (build time only)

Install

pip install tachyon-ipc

Quickstart

The consumer must start first.

# consumer
import tachyon

with tachyon.Bus.listen("/tmp/demo.sock", 1 << 16) as bus:
	for msg in bus:
		print(f"received {msg.size} bytes type_id={msg.type_id}")
		break
# producer
import tachyon

with tachyon.Bus.connect("/tmp/demo.sock") as bus:
	bus.send(b"hello tachyon", type_id=1)

Bus is a context manager. __exit__ destroys the bus and unmaps shared memory.

API

SPSC

Bus.listen(socket_path, capacity) creates an SHM arena and blocks until one producer connects. capacity must be a strictly positive power of two.

Bus.connect(socket_path) attaches to an existing arena.

bus.send(data, type_id=0) copies data into the ring buffer, commits, and flushes.

for msg in bus blocks until each message is available. Each msg is a Message(type_id, size, data) with a heap-owned bytes payload safe to retain indefinitely.

bus.drain_batch(max_msgs, spin_threshold) drains up to max_msgs in a single C crossing.

Zero-copy TX

with bus.send_zero_copy(size=64, type_id=7) as tx:
	with memoryview(tx) as m:
		m[:len(payload)] = payload
	tx.actual_size = len(payload)
# auto-flushes on context exit

Zero-copy RX

with bus.recv_zero_copy() as rx:
	with memoryview(rx) as m:
		snapshot = m.tobytes()  # copy before context exit
# slot committed on __exit__

RPC

Low-level

# callee
with tachyon.RpcBus.listen("/tmp/rpc.sock", 1 << 16, 1 << 16) as callee:
	with callee.serve() as rx:
		cid = rx.correlation_id
		with memoryview(rx) as m:
			reply = m.tobytes()
	callee.reply(cid, reply, msg_type=2)

# caller
with tachyon.RpcBus.connect("/tmp/rpc.sock") as caller:
	cid = caller.call(b"ping", msg_type=1)
	with caller.wait(cid) as rx:
		with memoryview(rx) as m:
			print(m.tobytes())

serve() must be exited (committed) before reply() to avoid holding both arena slots simultaneously.

Decorator API

import tachyon
from tachyon import tachyon_rpc, RpcDispatcher


@tachyon_rpc(msg_type=1)
def echo(payload: memoryview) -> bytes:
	return payload.tobytes()


dispatcher = RpcDispatcher()
dispatcher.register(echo)

# callee
with tachyon.RpcBus.listen("/tmp/rpc.sock", 1 << 16, 1 << 16) as callee:
	dispatcher.serve_forever(callee)

# caller
with tachyon.RpcBus.connect("/tmp/rpc.sock") as caller:
	response = echo.call(caller, b"hello")
	print(response)

@tachyon_rpc(msg_type) binds a memoryview -> bytes function to a message type. The handler receives a zero-copy memoryview valid only for the duration of the call. Call .tobytes() to retain.

RpcDispatcher.serve_forever(bus) runs the callee loop until KeyboardInterrupt or PeerDeadError. If no handler is registered for a received msg_type, a MSG_TYPE_ERROR reply is sent to the caller before raising locally. The caller is never left blocked.

RpcEndpoint.call(bus, payload, on_response=None) is the caller-side convenience wrapper. If on_response is provided, the response memoryview is passed directly (zero-copy). If None, returns bytes.

Error sentinel

MSG_TYPE_ERROR = 0xFFFF. When serve_once catches an unhandled msg_type or a handler exception, it sends a 2-byte error payload struct.pack("!H", unhandled_msg_type) with msg_type=0xFFFF. Callers can detect this with _decode_error(payload).

Batch RX

with bus.drain_batch(max_msgs=64) as batch:
	for msg in batch:
		print(msg.type_id, msg.actual_size)
# all slots committed on __exit__

Type ID encoding

from tachyon import make_type_id, route_id, msg_type

type_id = make_type_id(0, 42)  # == 42
route_id(type_id)  # 0
msg_type(type_id)  # 42

route_id >= 1 is reserved for RPC.

Error handling

from tachyon import TachyonError, PeerDeadError

try:
	with tachyon.Bus.connect("/tmp/demo.sock") as bus:
		bus.send(b"ping")
except PeerDeadError:
	# Bus entered FATAL_ERROR: corrupted header. Destroy immediately.
	pass
except TachyonError as e:
	print(e)

Thread safety

Bus and RpcBus are not thread-safe. Each direction must be used from at most one thread. Tachyon is SPSC, not MPSC.

Blocking calls (listen, for msg in bus, serve) park the calling OS thread. Do not call them from a thread that holds the GIL and must service other Python tasks. Release the GIL before blocking C calls: the CPython extension calls Py_BEGIN_ALLOW_THREADS internally.

NUMA binding

with tachyon.Bus.listen(path, 1 << 20) as bus:
	bus.set_numa_node(0)  # call before first message

No-op on macOS.

API surface

Symbol Description
Bus SPSC bus. Context manager.
RpcBus Bidirectional RPC bus. Context manager.
RpcDispatcher Routes incoming msg_type to registered RpcEndpoint handlers.
RpcEndpoint / @tachyon_rpc Decorator binding a memoryview -> bytes handler to a msg_type.
TxGuard Zero-copy TX slot (via send_zero_copy).
RxGuard Zero-copy RX slot (via recv_zero_copy or serve).
RxBatchGuard Batch of RX slots (via drain_batch).
Message Heap-owned message: type_id, size, data.
TachyonError Base exception for all native errors.
PeerDeadError Bus entered TACHYON_STATE_FATAL_ERROR.
MSG_TYPE_ERROR 0xFFFF. Sentinel for dispatcher error replies.

Limitations

Linux is the primary platform. set_numa_node, futex sleep, and memfd_create are Linux-specific. SPSC only. No peer crash detection.

License

Apache 2.0

Metadata

Release files for tachyon-ipc 0.5.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tachyon-ipc 0.5.1
File Size Uploaded
tachyon_ipc-0.5.1.tar.gz 49.2 kB Details

Release files / tachyon_ipc-0.5.1.tar.gz

Download URL tachyon_ipc-0.5.1.tar.gz
Size 49.2 kB
Tags Source
SHA-256 checksum
How to use checksums
3787b73eace9fa786d13ce4e118c3d665e2ac631db930fc08f2fe9ebc20e9383
BLAKE2b-256 checksum
How to use checksums
38e0f17f9dcd07ecca0d183b7b05a13fd768c45a749193000b6c5e45af15efc0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 9, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.5.1 This release

1 release file

0.5.0

1 release file

0.4.2

1 release file

0.4.1

1 release file

0.4.0

1 release file

0.3.5

1 release file

0.3.4

1 release file

0.3.3

1 release file

0.3.2

1 release file

0.3.1

1 release file

0.2.0

1 release file

0.1.3

1 release file

0.1.2

1 release file

0.1.1

1 release file

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page