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++20, 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++20 compiler (GCC 10+, Clang 13+, MSVC 2019 16.10+)
  • 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
./build/examples/hello_wait

# 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 (*)

(*) Windows limitation: WakeByAddressAll wakes only the calling process. A cross-process receive() may wait until timeout; unread messages can overflow the ring during that wait. Use a timeout within the ring's buffering budget, or poll. See ARCHITECTURE.md (Platform Abstraction).

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.9.1

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.9.1
File
kickmsg-0.9.1-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.12 abi3 Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 Details
kickmsg-0.9.1-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl CPython 3.12 abi3 Linux glibc 2.26+ ARM64, Linux glibc 2.28+ ARM64 Details
kickmsg-0.9.1-cp312-abi3-macosx_11_0_arm64.whl CPython 3.12 abi3 macOS 11.0+ ARM64 Details
kickmsg-0.9.1-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.9.1-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl CPython 3.11 CPython 3.11 Linux glibc 2.28+ ARM64, Linux glibc 2.26+ ARM64 Details
kickmsg-0.9.1-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details
kickmsg-0.9.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 Details
kickmsg-0.9.1-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.9.1-cp310-cp310-macosx_11_0_arm64.whl CPython 3.10 CPython 3.10 macOS 11.0+ ARM64 Details

Total release size: 10.8 MB

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

Download URL kickmsg-0.9.1-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 1.5 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
90bad80c3281c7b3db32f5552e1b63274ec16f4dbc967a0d7f06437a9ed6d0ef
BLAKE2b-256 checksum
How to use checksums
077b64a8ad992b51cb5990c59faead1b2c4143b4f0b482078c19192c2dafc5d6
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 Sep 25, 2026.

Transparency log

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

Download URL kickmsg-0.9.1-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Size 1.5 MB
Tags CPython 3.12 Linux glibc 2.26+ ARM64 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
5ea0a68926b8bd634f9c5aad7fd528aaea5fab55864ad901527c1a04cc2aa954
BLAKE2b-256 checksum
How to use checksums
4d171a691ee43793d88dcf0627702a283c76ec1757fd3d31ddec97cf46f91272
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 Sep 25, 2026.

Transparency log

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

Download URL kickmsg-0.9.1-cp312-abi3-macosx_11_0_arm64.whl
Size 517.9 kB
Tags CPython 3.12 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
b870f18b82dbae3ad816150905c16387a681e65cb2d7505e7d47f6d6bc7dae86
BLAKE2b-256 checksum
How to use checksums
bcaa86abfc5f9ff8f32fdec01f8994fb7933aec5506ff3a6f5adedfab030dd24
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 Sep 25, 2026.

Transparency log

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

Download URL kickmsg-0.9.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 1.5 MB
Tags CPython 3.11 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
c624f4e469bad733911f0554732a87693b3cdee195a9733a791f456852e7d824
BLAKE2b-256 checksum
How to use checksums
96459e7c3ef891b8ae787da7e7b2d4dade2adb950a8283c0e6e3101bbb68fcbe
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 Sep 25, 2026.

Transparency log

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

Download URL kickmsg-0.9.1-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Size 1.5 MB
Tags CPython 3.11 Linux glibc 2.26+ ARM64 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
ed99dd14fe8ac6659f019330c32668d8db3a74f1e55e1c00c25f9d4b65f65b5b
BLAKE2b-256 checksum
How to use checksums
8a3c5417e83e0bb2806dc9882e3293a3e67bbbaa39b1afe25c85cbb6ee8233b3
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 Sep 25, 2026.

Transparency log

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

Download URL kickmsg-0.9.1-cp311-cp311-macosx_11_0_arm64.whl
Size 517.1 kB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
34f9e5a6ab815c1e3a8a92f42d64f5ecaaca557c861fa447592624e4aedbfbf0
BLAKE2b-256 checksum
How to use checksums
0502eb2821d96f40b4a939867135fcee43cf3ebaff275c5abc1076fb11aa9c95
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 Sep 25, 2026.

Transparency log

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

Download URL kickmsg-0.9.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 1.5 MB
Tags CPython 3.10 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
263ad3e258bfdbd785ff959987074c542720b3aed0abe52843f6d7422c6b17f6
BLAKE2b-256 checksum
How to use checksums
fe4993e2333e4de1f82d74e684c3a30c352419a94b5e54c96a359e45d0716940
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 Sep 25, 2026.

Transparency log

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

Download URL kickmsg-0.9.1-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Size 1.5 MB
Tags CPython 3.10 Linux glibc 2.26+ ARM64 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
6bbc3b1d7bce89f0ee9f556b154ce475c1cd228aac03a8ea0eee22769ee25eee
BLAKE2b-256 checksum
How to use checksums
5c61c234ee00c1cf810adcc1977904139cd645c7cb5da6d69145dc68372b008c
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 Sep 25, 2026.

Transparency log

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

Download URL kickmsg-0.9.1-cp310-cp310-macosx_11_0_arm64.whl
Size 516.4 kB
Tags CPython 3.10 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
faf962e9fec80cbe584022d0a1e6955809ca02ebaca2a67de9fc511647d726ab
BLAKE2b-256 checksum
How to use checksums
1c7df4e7eb4621170a3fa1ac5b8bfcf907ef9de4e2cda96b3621e0fd04bd3ae8
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 Sep 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.9.1 This release

9 release files

0.9.0

9 release files

0.8.0

9 release files

0.7.0

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