Binions is a small set of focused Rust services that run side by side on one Linux host and coordinate over an internal event bus. There is no cluster to manage, no external message queue, and no container orchestration. This page explains the model at a glance — enough to understand how Binions works without reading the deep developer documentation.
The short version. Each background service (a daemon) does one job. Daemons talk by publishing and reading events. A playbook you write decides which events trigger which work, and how much of that work runs at once. Everything stays on your machine.
The entire Binions platform — every daemon, its data store, and the supporting infrastructure — lives on a single Linux machine. This is a deliberate design rule, not just a default for small setups. Components never talk over the network between hosts; they communicate over localhost only.
What this buys you:
systemctl status shows the health of the whole platform.You scale Binions vertically — by giving the host more RAM and CPU — rather than by adding more machines. Because daemons process work concurrently (see below), more CPU directly buys more throughput.
Daemons do not call each other directly. Instead, they exchange messages over a shared internal event bus. A daemon publishes an event when something happens, and any daemon that cares subscribes to receive it. This loose coupling lets each daemon work independently and recover on its own if something briefly fails.
Events come in a few clear kinds:
Every event carries a small envelope with its own ID and a correlation ID, so a whole workflow can be traced end to end. The bus keeps publishing latency well under a millisecond, and it processes each action exactly once with redelivery on failure — so the concurrency described below never drops or double-runs work.
Binions ships with thirteen native daemons. Each is a single, compiled Rust program that does one job and speaks only to the event bus.
| Daemon | What it does |
|---|---|
| playbook | The orchestrator. Reads your YAML playbooks, matches incoming events, and drives the steps that follow. It can keep many playbook runs in flight at the same time. |
| scheduler | A cron-style timer. Fires events at the times you define, so playbooks can run on a schedule. |
| mailbox | The email and messaging gateway. Receives and sends mail (and can bridge MQTT/AMQP message sources). |
| webhookcaller | Outbound HTTP. Calls any REST API or webhook endpoint — Slack, GitHub, your own services. |
| aiinjector | The AI gateway. Sends prompts to a language model to classify, extract, or summarize data. |
| database | Persistence. Runs queries and stores results across multiple backends — PostgreSQL, SQLite, MySQL/MariaDB, MongoDB, and Microsoft SQL Server. |
| datatransporter | File and object movement. Uploads and downloads to object storage and other file backends. |
| dataanaliser | Analytics. Computes statistics, detects anomalies, ranks and forecasts over your data. |
| modbus | Industrial gateway. Reads and writes PLCs and IO modules over MODBUS (TCP and RTU-over-TCP). |
| showman | Serves HTTP content — static pages and templated output — for dashboards and simple front ends. |
| traefiklinker | Manages routes on the edge router, so inbound traffic reaches the right place. |
| logger | The audit sink. Collects log events from every daemon into a single, searchable record. |
| cliconsole | The operator console. Lets you publish actions and watch facts from the command line. |
Behind the daemons sits a small infrastructure tier: Traefik as the edge router (the only component exposed to the outside world), object storage for files, and an optional tracing collector for distributed tracing. These support the platform but do not carry your business events.
For the full per-daemon reference — operations, configuration, and external dependencies — see Daemons reference.
The playbook daemon is the brain of the platform, and its YAML grammar is richer than a flat list of steps. Knowing the shape of it up front makes the rest of the documentation easier to follow. A playbook has a trigger (the fact that starts it), an optional mode, and a list of steps — and each step is exactly one of four kinds:
run steps a bounded number of times, with a hard iteration cap and an optional early-exit condition.The top-level mode field decides how those steps are paced:
run step waits for its own result fact before the next step begins, and that result is available to later steps as ${prev}. Every existing playbook behaves this way; nothing changes unless you opt in.run steps are fire-and-forget: the playbook emits the action and moves straight on without waiting. You then add a wait_for step to join only the results you actually need. One playbook can fan out many actions this way and collect them in a few barriers — high throughput instead of a long serial chain.Key idea. Saga mode keeps a workflow simple and strictly ordered; async mode trades that ordering for concurrency inside a single run. You pick per playbook — see Playbook anatomy for the step shapes and Playbook patterns for fan-out and join recipes.
A typical automation moves through the platform in a few crisp steps:
wait_for step.That five-step picture describes a single run. What the diagram does not show is how much happens at once underneath it:
Rather than thousands of app-specific connectors, several daemons use a small set of generic verbs that work across many providers. One instruction, many back ends:
Choosing a provider is just a field in your configuration — the playbook vocabulary stays the same, so existing automations keep working as new providers are added.
Only the edge router (Traefik) accepts connections from outside the host. Every other daemon listens on the loopback interface only, so nothing else is reachable from the network. Each daemon also runs under its own system user with hardened service settings.
Closed by default. Apart from the single edge router you choose to expose, the platform has no open ports. Your data, credentials, and automations never leave the host.
The whole stack is deliberately small. Running all at once — every daemon, its data stores, and the supporting infrastructure — the platform uses roughly half a gigabyte of RAM, and daemons answer health checks in well under a millisecond. That modest footprint is why the same packages run comfortably on hardware from a Raspberry Pi* to a rack server.
Small does not mean slow. Because daemons work concurrently and the orchestrator runs many playbooks in parallel, performance scales with the CPU you give the host:
* Raspberry Pi and other 64-bit ARM hardware are supported from the public 1.0 release. Binions is currently in alpha, and the alpha packages are for 64-bit x86 (amd64) only.