Skip to main content

Kickmsg

Lock-free shared-memory messaging library for inter-process communication.

Kickmsg provides MPMC publish/subscribe over shared memory with zero-copy receive, per-subscriber ring isolation, and crash resilience — all without locks or kernel-mediated synchronization on the hot path.

Features

  • Lock-free: all data paths use atomic CAS (Treiber stack, MPSC rings)
  • Zero-copy receive: SampleView pins slots via refcount, avoiding memcpy for large payloads
  • Per-subscriber isolation: a slow subscriber only overflows its own ring — fast subscribers are unaffected
  • Crash resilient: publisher crashes never deadlock the channel; bounded slot leaks are recoverable via GC
  • Topic-centric naming: subscribers connect by topic name, not publisher identity
  • Blackboard: shared-memory key/value state -- a late reader immediately sees the current value of every key, with its age and its writer's liveness; no heartbeat, no replay
  • C++17, no external dependencies beyond POSIX / Win32

Channel Patterns

Pattern API SHM name
PubSub (1-to-N) advertise / subscribe /{prefix}_{topic}
Broadcast (N-to-N) join_broadcast /{prefix}_broadcast_{channel}
Mailbox (N-to-1) create_mailbox / open_mailbox /{prefix}_{owner}_mbx_{tag}
Blackboard (state) blackboard / declare / observe /{prefix}_bb_{name}

Installation

For Python (also installs the kickmsg CLI):

pip install kickmsg

Pre-built wheels are published for CPython 3.10–3.12 on Linux x86_64 / aarch64 (manylinux_2_28) and macOS 11+ (universal2). On any other platform pip will fall back to a source build, which needs the build prerequisites.

For C++ only, see Building or use the Conan recipe in conan/all.

Quick Start

#include <kickmsg/Publisher.h>
#include <kickmsg/Subscriber.h>

// Create a channel
kickmsg::channel::Config cfg;
cfg.max_subscribers   = 4;
cfg.sub_ring_capacity = 64;
cfg.pool_size         = 256;
cfg.max_payload_size  = 4096;

auto region = kickmsg::SharedRegion::create(
    "/my_topic", kickmsg::channel::PubSub, cfg);

// Subscribe, then publish
kickmsg::Subscriber sub(region);
kickmsg::Publisher  pub(region);

uint32_t value = 42;
pub.send(&value, sizeof(value));

auto sample = sub.try_receive();
// sample->data(), sample->len(), sample->ring_pos()

Node API (topic-centric)

#include <kickmsg/Node.h>

kickmsg::Node pub_node("sensor", "myapp");
auto pub = pub_node.advertise("imu");

// Any node can subscribe by topic name alone
kickmsg::Node sub_node("logger", "myapp");
auto sub = sub_node.subscribe("imu");

Zero-copy receive

auto view = sub.try_receive_view();
// view->data() points directly into shared memory
// slot is pinned until view is destroyed

Blocking receive

auto sample = sub.receive(100ms);
// blocks via futex until data arrives or timeout

Optional payload schema descriptor

// Bake a schema descriptor into the region at creation.
kickmsg::SchemaInfo info{};
info.identity = my_identity_hash();   // user-defined bytes
info.layout   = my_layout_hash();     // user-defined bytes
std::snprintf(info.name, sizeof(info.name), "my/Pose");
info.version  = 2;

kickmsg::channel::Config cfg;
cfg.schema = info;
auto region = kickmsg::SharedRegion::create("/pose_topic", kickmsg::channel::PubSub, cfg);

// Any process can read it back and decide what to do on mismatch.
auto schema = region.schema();
if (schema and schema->version != 2) { /* user-defined policy */ }

The library stores the descriptor in the header but never interprets it — users choose how to compute identity/layout fingerprints and how to react to mismatches.

Blackboard (state, not stream)

A Subscriber starts at the ring's current position and sees nothing published before it attached. When what you have is state -- a lifecycle, a mode, a calibration -- use a blackboard: the writer publishes once and stops, and any reader that attaches later sees the current value at once.

#include <kickmsg/Node.h>

// Writer: declares the keys it owns, publishes once, stops.
kickmsg::Node  arm("arm_driver", "demo");
auto&          board = arm.blackboard("robot");
auto           state = board.declare("arm/state");   // labelled "arm_driver"
state.write(uint32_t{ACTIVE});

// Reader: constructed AFTER the write, reads it immediately.
kickmsg::Node  hmi("hmi", "demo");
auto           view = hmi.blackboard("robot").observe("arm/state");

uint32_t value = 0;
auto     out   = view.read(value);          // out.status == blackboard::Ok
// out.updated_at_ns -> how old it is;  view.owner_alive() -> is the writer up?

// Block until any key on the board changes, instead of polling.
uint64_t seq = board.change_seq();
if (board.wait(seq, 100ms)) { view.read(value); }

One declared writer per key; a key whose owner died keeps its last value and can be taken over by a restarted writer. See ARCHITECTURE.md for the protocol.

Health diagnostics and crash recovery

// Periodic health check (read-only, safe under live traffic)
auto report = region.diagnose();
// report.locked_entries, report.retired_rings,
// report.draining_rings, report.live_rings

// Repair poisoned entries (safe under live traffic)
region.repair_locked_entries();

// Reset retired rings (after confirming crashed publisher is gone)
region.reset_retired_rings();

// Reclaim leaked slots (requires full quiescence)
region.reclaim_orphaned_slots();

CLI (kickmsg)

Installing the Python wheel puts a kickmsg command on $PATH that inspects running channels via a shared participant registry (one per namespace, backed by a SHM region at /{namespace}_registry). Works identically on Linux, macOS, and Windows — no /dev/shm filesystem walk required.

kickmsg list                        # topic-centric enumeration
kickmsg list -o name,pub,sub,stall  # ps-style column selection
kickmsg info  <shm>                 # static header metadata
kickmsg stats <shm>                 # runtime counters (write_pos / dropped / lost)
kickmsg watch <shm>                 # top-like live view, msg/s rates (interactive; Ctrl-C to quit)
kickmsg diagnose <shm>              # wraps SharedRegion::diagnose()
kickmsg repair   <shm> [--locked]   # run repair primitives
kickmsg schema <shm>                # focused schema descriptor view
kickmsg schema-diff <a> <b>         # field-by-field schema comparison
kickmsg blackboard <name>           # key table: size, freshness, owner, liveness
kickmsg blackboard-watch <name>     # top-like live view, updates/s per key

All subcommands accept --json for scripting.

Programmatic use (GUIs, exporters)

The same data the CLI renders is available as typed dataclasses through kickmsg.diagnostics, so a GUI can consume it without shelling out:

from kickmsg import diagnostics as diag

for topic in diag.list_topics(namespace="kickmsg"):
    print(topic.shm_name, len(topic.producers), len(topic.consumers))

stats = diag.stats("/kickmsg_telemetry")
for ring in stats.rings:
    if ring.state == "live":
        print(ring.write_pos, ring.dropped_count, ring.lost_count)

# Live updates (generator — caller drives the loop)
for frame in diag.watch("/kickmsg_telemetry", interval=1.0):
    gui.update(frame.stats, frame.rates_msg_per_sec)

# Blackboards are addressed by (name, namespace), not by shm path
board = diag.blackboard("robot", kmsg_namespace="demo")
for key in board.keys:
    print(key.key, key.value_len, key.age_seconds, key.owner_alive)

Building

Prerequisites

  • C++17 compiler (GCC 10+, Clang 12+, MSVC 2019+)
  • CMake 3.15+
  • Conan 2.x (for test/benchmark dependencies)

Build

The project's own scripts do the dependency install and the CMake configure together, which is the least error-prone route:

scripts/configure.sh build --with=unit_tests   # record the option set
scripts/setup_build.sh build                   # conan install + cmake configure
cmake --build build

By hand:

conan install conan/conanfile.py -of=build --build=missing -o unit_tests=True

cmake -S . -B build \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_PREFIX_PATH=build \
    -DBUILD_UNIT_TESTS=ON \
    -DBUILD_EXAMPLES=ON
cmake --build build

Re-run the cmake -S . -B build line every time you re-run conan install. Skipping it reuses the existing CMake cache, which reports the dependency as found -- Conan: Component target declared 'GTest::gtest' -- while dropping its include paths, so the build fails with gtest/gtest.h: No such file or directory even though Conan just said Already installed. Deleting the build directory has the same effect.

# Run the whole suite: unit, stress, crash, stall-repair, mp-stress,
# blackboard-crash, registry-stress
ctest --test-dir build --output-on-failure

# Run C++ examples
./build/examples/hello_pubsub
./build/examples/hello_zerocopy
./build/examples/hello_broadcast
./build/examples/hello_diagnose
./build/examples/hello_schema
./build/examples/hello_schema_late_publisher
./build/examples/hello_lowlevel
./build/examples/hello_blackboard

# Run Python examples (after `pip install kickmsg`)
python examples/python/hello_pubsub.py
python examples/python/hello_camera_zerocopy.py    # zero-copy with memoryview
python examples/python/hello_schema.py
python examples/python/hello_blackboard.py
python examples/python/cli_playground.py           # long-running, drive the `kickmsg` CLI against it

To prove kickmsg works on your own hardware -- the validation ladder from a quick ctest gate to a multi-hour contention soak with a single VERDICT: ALL CLEAN -- see tests/README.md.

As a subdirectory

add_subdirectory(kickmsg)
target_link_libraries(my_app PRIVATE kickmsg)

CMake Options

Option Default Description
BUILD_UNIT_TESTS OFF Build unit and stress tests
BUILD_EXAMPLES OFF Build example programs
BUILD_BENCHMARKS OFF Build benchmarks (requires Google Benchmark)
ENABLE_TSAN OFF Enable ThreadSanitizer

Security

Shared-memory objects are created with mode 0600 (owner-only) on Linux and macOS, so channel payloads are not readable by other users on a multi-user host. To share channels across users, set the KICKMSG_SHM_MODE environment variable to an octal mode (e.g. KICKMSG_SHM_MODE=0666) in every process that creates regions — openers are unaffected. The value is parsed once per process; an invalid value falls back to 0600 with a warning on stderr.

Platform Support

Platform SharedMemory Futex
Linux shm_open / mmap SYS_futex
macOS shm_open / mmap __ulock_wait / __ulock_wake
Windows CreateFileMapping / MapViewOfFile WaitOnAddress / WakeByAddressAll

Actively validated on Linux x86-64, Linux ARM64 (Raspberry Pi 4B, 12 h continuous stress), and Darwin ARM64 (Apple Silicon, 12 h continuous stress: 2660 passes, 0 failures, 0 reorders) via scripts/validate.sh and tests/endurance.sh.

Architecture

See ARCHITECTURE.md for the full design: shared-memory layout, concurrency model, publish/subscribe flows, crash resilience, garbage collection, and ABA safety analysis.

Troubleshooting

See TROUBLESHOOTING.md for common operational gotchas: stale segments after a crash, the diagnose/repair flow, SHM naming and length limits, permission errors, and platform-specific notes (macOS PSHMNAMLEN, Windows session isolation, Linux /dev/shm sizing).

License

CeCILL-C

Release files for kickmsg 0.7.0

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

Built distributions (wheels)

Table of built distributions (wheels) for kickmsg 0.7.0
File
kickmsg-0.7.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.12 abi3 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
kickmsg-0.7.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl CPython 3.12 abi3 Linux glibc 2.28+ ARM64, Linux glibc 2.26+ ARM64 Details
kickmsg-0.7.0-cp312-abi3-macosx_11_0_arm64.whl CPython 3.12 abi3 macOS 11.0+ ARM64 Details
kickmsg-0.7.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
kickmsg-0.7.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl CPython 3.11 CPython 3.11 Linux glibc 2.26+ ARM64, Linux glibc 2.28+ ARM64 Details
kickmsg-0.7.0-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details
kickmsg-0.7.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
kickmsg-0.7.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl CPython 3.10 CPython 3.10 Linux glibc 2.26+ ARM64, Linux glibc 2.28+ ARM64 Details
kickmsg-0.7.0-cp310-cp310-macosx_11_0_arm64.whl CPython 3.10 CPython 3.10 macOS 11.0+ ARM64 Details

Total release size: 8.6 MB

Release files / kickmsg-0.7.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL kickmsg-0.7.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 1.2 MB
Tags CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
96e7e60cfd78241d253856a96fccc75e8c6c03e36d3b8535fd6e69e945ddff45
BLAKE2b-256 checksum
How to use checksums
5278be39c92d43c6c9534d5f4938fe2e315ec0dd875c58aec00a2467fc92646b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.8

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 Aug 26, 2026.

Transparency log

Release files / kickmsg-0.7.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl

Download URL kickmsg-0.7.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Size 1.2 MB
Tags CPython 3.12 Linux glibc 2.26+ ARM64 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
ae596a83423abf064fcdbd5b62e1d8fe9a8a15b4cf2d241725f79867de7063e2
BLAKE2b-256 checksum
How to use checksums
e6c57eb3c5ab4cb79c2295585192255fed5471a14ae55effdad9037015248695
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.8

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 Aug 26, 2026.

Transparency log

Release files / kickmsg-0.7.0-cp312-abi3-macosx_11_0_arm64.whl

Download URL kickmsg-0.7.0-cp312-abi3-macosx_11_0_arm64.whl
Size 447.9 kB
Tags CPython 3.12 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
441b5ea52e9564596d9adb9f66342ff549a181fa4d50e16401da053eb05fe113
BLAKE2b-256 checksum
How to use checksums
e2524c8b67d0e6b21d151a0dea05350a4f34d2d85ffac3ffd739a9cee89f738b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.8

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 Aug 26, 2026.

Transparency log

Release files / kickmsg-0.7.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL kickmsg-0.7.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 1.2 MB
Tags CPython 3.11 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
6c8d45607c432828f2d0d5c36cc57d2954698606fc44722c19f49b75bfdd9238
BLAKE2b-256 checksum
How to use checksums
a045dc72053f94fca5440b96ae227645d089e89bd66193b4f67bf0676b1a369c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.8

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 Aug 26, 2026.

Transparency log

Release files / kickmsg-0.7.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl

Download URL kickmsg-0.7.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Size 1.2 MB
Tags CPython 3.11 Linux glibc 2.26+ ARM64 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
c7c1b26bc052c9a0b1d2dc5d52d7b6670d02a52cd9ca4291d2dc773197e605fd
BLAKE2b-256 checksum
How to use checksums
51fa2e928a6c0fc5c785a7a2375a30a0ad2d98ff96877be4b10cd89e4ab4daff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.8

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 Aug 26, 2026.

Transparency log

Release files / kickmsg-0.7.0-cp311-cp311-macosx_11_0_arm64.whl

Download URL kickmsg-0.7.0-cp311-cp311-macosx_11_0_arm64.whl
Size 447.2 kB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
bbdd8f18bd0e1b7dba4ef18cfc9c289b3f41cad9ee551a3a955fc3854eca193a
BLAKE2b-256 checksum
How to use checksums
f35a391cd0ebc5f2566f3bb787b10d8ececb11d6c418a8a1f813ab12f2c30b16
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.8

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 Aug 26, 2026.

Transparency log

Release files / kickmsg-0.7.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL kickmsg-0.7.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 1.2 MB
Tags CPython 3.10 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
87f825f0523e856c426f4b8b5309bacc410541dd935254306b8063c4a3d5d9a5
BLAKE2b-256 checksum
How to use checksums
8dcf206ee79bd13cfe9254bf14c66e5865b0c502d08c8d70ced4edacd8cea0a7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.8

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 Aug 26, 2026.

Transparency log

Release files / kickmsg-0.7.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl

Download URL kickmsg-0.7.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Size 1.2 MB
Tags CPython 3.10 Linux glibc 2.26+ ARM64 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
dfa4b8db5a8579dc4e4225ed050f576a06689e95591fe23fb70ef1c1822ec085
BLAKE2b-256 checksum
How to use checksums
9bcf38cf68e8833ff6a95338d6a1134cd041dd26430736799ce8a319d2a75ceb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.8

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 Aug 26, 2026.

Transparency log

Release files / kickmsg-0.7.0-cp310-cp310-macosx_11_0_arm64.whl

Download URL kickmsg-0.7.0-cp310-cp310-macosx_11_0_arm64.whl
Size 446.4 kB
Tags CPython 3.10 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
e0ce0c6070ead26064b1bd4ce65a1337120abc24cb4e31648b6d29e6d7b83a3a
BLAKE2b-256 checksum
How to use checksums
85b693ab22c37bf836d86b0657e7bf95ed4712507d52bcdc0cdc86d91d17f45f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.8

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 Aug 26, 2026.

Transparency log

Release history Release notifications | RSS feed

0.9.1

9 release files

0.9.0

9 release files

0.8.0

9 release files

This release

0.7.0 This release

9 release files

0.6.3

9 release files

0.6.2

9 release files

0.6.1

9 release files

0.6.0

9 release files

0.5.0

9 release files

0.4.0

9 release files

0.3.0

9 release files

0.2.0

9 release files

0.1.0

9 release files

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