Self-hosted monitoring · AGPLv3 · in development
Signals stacked and
left for someone to read.
Cairn OBS watches your networks, hosts, services and clusters, and answers "is everything OK?" in one screen. An agent on each host reports to one server, which judges the readings, draws the maps, sends the alerts and writes the reports. It reads and never changes anything, and it runs on your own hardware, from a single container to a cluster watching thousands of VMs and pods.
A test fleet of 121 hosts, two clusters, three hypervisors and two Pure arrays.
Explore
One page, five things worth reading about
Each section below stands on its own. Jump to the piece you care about.
Features
Hosts, checks, maps, clusters, storage arrays, Vault, alerts and reports, with nothing held back for a paid tier.
See what it watches →How it works
One agent per host, one server, and a join line that brings a new host in over mutual TLS in under a minute.
See the pieces →Where it runs
One container on a small server, or several copies on PostgreSQL in Kubernetes or OpenShift, upgraded one at a time.
See the options →License
AGPLv3, the whole thing. No paid tier and no locked features.
Read the terms →About
What the name means, and why a monitor should be something you can read the source of.
Read the story →Features
Everything you run, on one screen
Hosts, services, clusters, storage and secrets, judged in one place, so one broken thing shows as one problem and not forty alerts.
Hosts and services
CPU, memory, disks and their fill dates, network, RAID and SMART, Docker containers and systemd units that should be running, and backups that should be fresh. Tell it what's running now and it expects that from then on.
Checks from every side
Websites, TLS certificates, DNS records, mail and other servers' banners, open ports and ping, run from each host. A service is down only when two vantage points agree, so one bad network path doesn't wake anyone.
Maps drawn from what's running
The network map and the service map are worked out from what the agents see, interfaces, tunnels, containers and listening services, not from a file someone forgot to update. Correct them once and the corrections stick.
Clusters and VMs
Pods and VMs on Kubernetes, OpenShift and OKD, KubeVirt, libvirt, Proxmox, vSphere and Nutanix, read from their APIs. No agent inside every pod or VM, and a VM is linked to the host it runs on.
Storage and secrets
Pure FlashArray and FlashBlade health, capacity and performance history, matched to the volumes your clusters use. HashiCorp Vault and OpenBao seal, HA and Raft state, leases and every PKI certificate.
Alerts and reports
Alerts to ntfy, Discord, email, PagerDuty or a webhook, each with its own level, plus maintenance windows and acknowledgements. Reports on uptime, incidents, certificate expiry, disk forecasts and backup freshness.
Read-only
It looks, it never touches
There's no remote shell and no "restart this" button. The agent reads the host, and the few things that need root go through a small helper that can only read. A stolen Cairn OBS session shows someone your dashboards. It doesn't hand them your servers.
- No commands run on monitored hosts, ever
- Read-only API tokens for clusters, arrays and Vault
- Every change to settings is in the audit log
Sign-in
Your directory, your roles
Start with local users, with passkeys or a password and a one-time code, then connect any OpenID Connect provider: Okta, Entra ID, Google, Keycloak and the rest. Viewers see the dashboards, operators also see log lines and the audit log, and admins change settings.
- Local users with passkeys, or password plus TOTP
- Generic OpenID Connect, roles from groups or addresses
- Viewer, operator and admin roles
How it works
One agent per host, one server
obs-beacon-agent reads each host and reports to obs-beacond, which judges the readings, runs the alerts and serves the web interface.
agents → obs-beacond → {database, web interface, alerts}
Add a host with one line
Add host gives you a single install command with a one-time join token. The agent installs from the package, makes its own key, and the server's built-in certificate authority signs it. The token expires in an hour and works once.
Mutual TLS, always
Agents and the server talk over TLS with a client certificate on every agent. Nothing is plain HTTP, and nothing depends on a VPN to be safe.
Nothing lost when the link drops
If the server can't be reached, the agent queues its reports on disk and sends them when it's back, so the history has no hole in it.
Configure it in the browser
Checks, alert channels, maintenance windows and expected containers are set in the web interface. Prefer files? A config file wins over the interface for its section, and you can export and import YAML.
One cluster agent per cluster
A cluster agent reads the Kubernetes API and the hypervisors' APIs and reports workloads in bulk, so thousands of pods and VMs come in without thousands of agents.
Signed releases
Every release has .deb and .rpm packages and static binaries for amd64 and arm64, checked against SHA256SUMS signed with the Cairn OBS minisign key.
Where it runs
One container, or a cluster of them
The same server binary runs as a single container on a small box, or as several copies sharing PostgreSQL in Kubernetes or OpenShift.
Small
One container, one file
Install the server package, or run its container with Docker or Podman. It keeps everything in one SQLite file, gets its own certificate from Let's Encrypt if you give it a hostname, and prints a one-time setup link on first start. Nothing else to run.
- .deb and .rpm packages, or one container
- Built-in ACME for its own certificate
- First admin made from a one-time link
Large
Several copies on PostgreSQL
For a big fleet, run several copies on one PostgreSQL database. Only one of them sends alerts at a time, and they upgrade one by one, so the web interface and the agents' endpoints stay up through an upgrade. It's built to watch thousands of VMs, pods and containers; what testing measured is below.
- Runs under OpenShift's restricted-v2 security context, unchanged
- Kustomize bases for OpenShift, OKD and plain Kubernetes
- Rolling upgrades with no gap
load balancer → copies of obs-beacond → one PostgreSQL
| Part | Choice | Why |
|---|---|---|
| Server and agent | Go | Static binaries with no runtime to install, for amd64 and arm64. |
| Web interface | Svelte 5, TypeScript | Built to static files and served by the server itself, so there's no second service. |
| Storage | SQLite or PostgreSQL | One file for a small install; a shared database when you run several copies. |
| Hosts | Debian, Ubuntu, RHEL family | With systemd, on amd64 and arm64. Windows, Alpine and macOS agents are planned. |
| Clusters | Kubernetes, OpenShift, OKD | Read-only service account. The server image runs as any user ID with a read-only root. |
| Releases | minisign, SHA256SUMS | Every file checked, and the checksum list signed. |
Measured
1,000 hosts and 10,000 workloads, nothing lost
The load test runs fake agents and fake clusters against real copies of obs-beacond. On 13 November 2026, on one workstation: two copies on PostgreSQL, 1,000 host agents reporting every 15 seconds, and three clusters with 9,000 pods, 900 VMs and their controllers between them, two pods changing every second in each. Partway through, both copies were restarted one at a time. Eight minutes:
| Measured | Result | Detail |
|---|---|---|
| Host reports | 2.6 ms at p99 | 32,000 sent, 32,000 taken, none lost, through both restarts. |
| Pages | 19 ms at p99 | A page every half second, the Workloads and Clusters pages among them. |
| Cluster changes | 61 ms at p95 | From a change in one cluster to it showing on both copies. |
| Restarts | 3.3 s | Each copy out of the load balancer within 0.5 s of stopping and ready again 3.3 s later, with alerts moving to the other copy. |
| Memory | About 75 MB | Per copy, for all 1,000 hosts and the three clusters. |
License
AGPLv3 — the whole thing, no exceptions
Every feature on this page ships under the same license. There's no paid tier and no locked features.
Self-host it, fork it, run it as a service. The license terms are the same for everyone, including us. There's no separate commercial edition: the code you can read is the code that runs.
AGPLv3's network-use clause means that if you change Cairn OBS and offer it to others over a network, including as a hosted service, you have to make your changed source available to those users too. That's on purpose. It's the same protection that keeps this project from being taken closed-source downstream.
Full license text
The complete AGPLv3 terms apply to everything in the repository, with no per-component exceptions.
About the name
A cairn is a message left for
whoever comes after you.
The name is the working metaphor for what this monitor does.
The name
Stones, stacked so they can be read at a glance
A cairn is one of the oldest pieces of infrastructure people build: a pile of stones, placed by hand, left on a trail so that someone who comes later, a stranger who never met the person who built it, can look at it and know someone was here, and this is the way through. Hill-walkers use them. Arctic travellers build Inuksuit for the same reason. Long before GPS, a cairn was the original out-of-band signal: unattended, and readable by anyone who knew how.
That's what a monitor should be. Whoever is on call at 3 a.m. didn't set it up and wasn't there when the problem started. They need to look at one screen and see what's wrong, where, and what it's taking down with it. Each reading is a pebble. The monitor is the cairn: the stones stacked into something you can find your way by, in exactly the conditions a cairn was built for, poor visibility and somebody who needs to get through.
Signals stacked, and left for someone to read.
OBS is just what it says on the label: observability.
Why this exists
Monitoring shouldn't be a project of its own
Most monitoring ends up as one of two things. A hosted service that bills per host and holds your data somewhere else, or a stack you assemble yourself: a metrics store, an exporter for every kind of thing, a dashboard tool, an alert router, and a pile of hand-written configuration tying them together, which nobody has time to keep current.
Cairn OBS is one agent per host and one server. It works out the layout from what's actually running, it's set up in the browser, and it reads clusters, hypervisors, storage arrays and Vault directly. It never runs commands on what it watches. And it ships AGPLv3, so the monitor you depend on during an outage is one whose source you can read.
It started as the monitor for Coffey Labs' own servers, and it runs there first. Log aggregation, the original Cairn OBS, comes back later, rebuilt on this design and fed by the same agent.