Skip to content

Topologies

One binary, six roles. Every deployment shape below is the same jaque executable started with a different -target — nothing to build separately, nothing to install differently per role.

All: one process owns the whole check loop; UI, API and metrics are served from it toojaque -target allscheduleexecutefoldappend+ UI/API + /metrics

Schedules and executes checks in the same process. Requires -config. Forbids -queue (nothing to dispatch checks to) and -notifier-id (there’s no separate notifier identity to name).

Engine: schedules and dispatches work to a queue, never executes a check itselfjaque -target engineowns the check loopqueue(memory/NATS)workresult

Decides what and when, but never runs a check itself — it publishes each one to -queue and waits for the result. Requires -config and -queue. Forbids -notifier-id.

Worker: pulls work from the queue and executes it, no config or event logjaque -target workerruns the checksqueue(memory/NATS)workresult

No config, no event log, no projection — it only pulls work items from -queue and executes them. Requires -queue; forbids -config, -coordination, -heartbeat-ttl, and every notification flag. Needs its own disk: any legacy plugin or WASM module a remote check uses must be installed on the worker’s machine, not the engine’s.

UI: read-only projection that follows the event log and submits commands over jaque.work.cmd.ingress for an engine to claimjaque -target uiprojection + dashboardNATS JetStreameventlog + coordinationfollowcmd ingress

Read-only: follows the event log and serves the dashboard/API, never schedules or runs a check, never handles SIGHUP. Requires -config (for labels, views, the dependency graph). Forbids -queue, -command-file, -events-out, -sink, -archive, both -livestatus-* flags, -heartbeat-ttl, and every notification flag. With -coordination pointed at the shared store, commands it receives are forwarded to the engine fleet (jaque.work.cmd.ingress) fire-and-forget; without it, writes are rejected with 503. -target ui never joins engine membership.

Sink: follows the event log for perfdata onlyjaque -target sinkperfdata onlyevent log(shared)follow

Only perfdata (metrics-input) sinks, on its own sink/membership/ bucket and a -sink-id (hostname by default). Requires -config. Forbids -queue, -command-file, -events-out, -archive, both -livestatus-* flags, -snapshot-out, -api-token, every SMTP/Telegram flag, and every notification flag — none of that surface exists in this role. -sinks selects which of the CUE config’s sinks: block this process runs; empty runs all of them. A sink declared with input: "events" is rejected for this target — no events-input sink runs under -target sink. This role does not reconcile its sink set on SIGHUP: restart the process to pick up an added, removed, or changed sink.

Notifier: follows the event log for notification delivery onlyjaque -target notifierdelivery onlyevent log(shared)follow

Only notification delivery, on its own notifier/membership/ bucket (sibling to membership/ and sink/membership/, not nested under either) and a -notifier-id. Requires -config (contacts and policies live there). Forbids -queue, -sink, -archive, -command-file, -events-out, -snapshot-out, both -livestatus-* flags, -api-token, and -notify-delivery (that flag belongs to all/engine, which decide where delivery happens — not to the notifier that is the delivery target). Accepts -smtp-*, -telegram-token, -notify-workers, -notify-queue.

Every deployment sits somewhere on two independent axes: how many processes (one -target all, or one process per role) and how many engines (one, or several sharing ownership of the object set). The two axes compose — production is usually both split by role and running more than one engine. The three shapes below are the useful corners of that grid, not three rungs of a ladder.

Standalone: one process owns the whole check loop, nothing crosses a network boundaryjaque -target allscheduleexecutefoldappendeventlog: embedded JetStream, in-processOne process. Nothing crosses a network boundary.

Everything in one process. See Overview for when this is enough.

Split over external NATS: engine dispatches to worker through one JetStream, ui/sink/notifier follow the same logjaque -target engineowns the check loopNATS JetStreamexternal-target workerruns the checks-queue-eventlogfolds-target ui-target sink-target notifiereach follows the log on its own membership bucket

Every role points -eventlog and -coordination at the same external JetStream. engine dispatches work over -queue nats://...; one or more worker processes pull it, scoped by -zones (see below). ui, sink, and notifier each follow the log independently, each scaling on its own membership bucket.

Splitting by role buys scale for worker/ui/sink/notifier and network isolation between them. It does not buy availability of the check loop itself: there is still exactly one engine process, and if it dies checks stop until it comes back. (c) is the second axis that fixes that — the two combine.

HA: rendezvous-hashed engines share one external JetStream for both the event log and coordinationrendezvous hash (HRW) over the live engines-target engine-target engine-target engineNATS JetStreameventlog + coordinationreplicas: 3+ — active/active, every engine owns a share, none idlereplicas: 2 — active/passive failover: the survivor takes over

This is (b)’s second axis, not a replacement for it: the same role split, with more than one engine process instead of one. See Cluster and coordination for how membership, rendezvous-hashed ownership, heartbeats and epoch fencing combine to make that safe.

-zones (default default, comma-separated) is which zones a worker serves. Each host in CUE carries a zone (default "default"); each service inherits its host’s zone unless it sets its own. The engine publishes each check to its object’s zone’s queue; only a worker subscribed to that zone picks it up — the mechanism for routing checks to workers that can actually reach a given network segment.

A future outbound-gRPC, mTLS remote agent is planned (roadmap phase 7) for sites where even the pull-based worker model doesn’t fit — it does not exist yet. Today, cross-network execution is the engine/worker split above, over a queue both sides can reach.