Signal conditioning, transformation, and routing in a NATS-native message processor.
monoblok speaks NATS.
Point existing publishers at it or have it subscribe to existing subjects. Declare the processing rules you need, and monoblok republishes clean, actionable subjects for subscribers.
Rounding. Deadbands. Squelch. Aggregation. Moving averages. OHLC. Derived alerts.
Fix noisy raw streams once, not in every subscriber.
It is not uncommon for systems to contain some caretaker services that subscribe to ingress NATS subjects to clean up and republish a raw stream before the real business starts. This might include rounding, dedup, deadband, JSON demux, OHLC bars, threshold alerts and so on. High velocity or miniscule changes don't always have value downstream. monoblok lets you declare that tidying work once, leveraging efficient implementations of common tasks as rules at the broker, instead of writing rounding logic N times in N services.
Declare it once, as rules, at the edge.
Rules live in patchbay, a small DSL which can be expressed as YAML, EDN or JSON. A walked example lives in patchbay.edn. You can also write patchbay files as YAML.
patchbay also lends itself well to help from coding assistants when fed AGENTS_PATCHBAY.md (to be honest the agent instructions are human-parseable if you prefer a succinct primer. There is a fuller patchbay guide and cheatsheet.
- Tap into existing NATS: monoblok subscribes to selected subjects on your NATS environment, treats them as private patchbay input, then emits back only the cleaned or derived subjects your rules choose.
- Signal conditioning front door: publishers send raw events to monoblok, monoblok cleans them, then forwards selected subjects to a NATS cluster.
- Standalone broker: NATS clients connect directly to monoblok for lightweight NATS-core pub/sub with signal conditioning built in.
monoblok is written in C with libuv and builds on Linux and macOS. It aims to be simple, lightweight and fast, even on entry level/shared hardware. Smoke tests and load checks are part of the build; dedicated benchmark helpers live in scripts/. The saved benchmark runs span up to 2-18 million msgs/sec across a 2-core ARM VPS, an 8-core x86_64 VPS, and an Apple Silicon M4 Mac mini for simple publish and fan-out workloads. Treat those numbers as directional samples/trends and not capacity promises in the real world. See running tests for tests that exercise the router and parser without network.
tinyblok is an implementation for microcontrollers relaying cleaned sensor data into NATS.
See Overview, Patchbay, and the runnable files in examples/ to better get a feel. There's a demo server. Also, there's the introductory blog post and friends.
curl -fsSL https://raw.githubusercontent.com/lexvicacom/monoblok/main/scripts/start.sh | bashThe release helper downloads the latest monoblok (macOS/Linux) and extracts it into the current directory. To run the unpacked binary:
./monoblok-*/monoblok --port 14222 --patchbay ./monoblok-*/patchbay.ednThe directory contains runnable examples. Run the .sh files.
To add as a service on systemd Linux, run scripts/install-systemd.sh.
Multi-arch image:
docker run --rm -p 14222:14222 ghcr.io/lexvicacom/monoblok:latest --port 14222cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
./build/monoblok --port 14222 --patchbay patchbay.ednCompiles cleanly on macOS and Linux. Dependencies are vendored. System openssl required.
cmake -S . -B build
cmake --build build
ctest --test-dir build --output-on-failureFast integration smoke:
cmake --build build --target smokesmoke runs the TCP server smoke, patchbay soundcheck, load-smoke, and
the larger load-soak profile.
The subchecks can also be run directly:
cmake --build build --target soundcheck
cmake --build build --target load-smoke
cmake --build build --target load-soakload-smoke starts a temporary daemon and verifies exact TCP fan-out plus
derived moving-avg, moving-sum, and count! streams. load-soak runs the
same check with a heavier subscriber/message profile.
Benchmark helpers are separate from the test targets because they depend on the
NATS CLI, and the comparison script uses nats-server when available:
scripts/bench.sh
scripts/bench-with-nats-server.shSaved sample output lives in bench-results/. On Linux these
scripts default to monoblok's opt-in libuv io_uring path to match the saved
runs; pass --epoll to benchmark the production-default epoll path.
I'd love to hear from anyone who tries monoblok out and finds it useful.
It's open source, without restrictions (per MIT license re attribution) or paid commercial features. However, my company provides services around monoblok. I'd be happy to learn about your environment, requirements and work with you to deliver a proof of concept, case study or complete solution.
MIT. See LICENSE.

