Health Monitor
Enroll servers with one command, watch live metrics and the 0–1000 health score, run benchmarks, and manage the xdpd fleet daemon from the console.
Last updated
On this page
Health Monitor is the fleet console: a small open-source daemon (xdpd) on your
server reports facts, live samples, VMs and events every 15 seconds, and the
dashboard turns that into a health score, charts, one-click product installs and
benchmarks. Servers connect through "Server OAuth" — no API keys to paste.
Enroll a server
Open the dashboard overview and choose Connect a service → Your server (Server OAuth) (or Add a server (Server OAuth) on the Servers card). The modal mints a one-time enroll token and shows the install command:
curl -fsSL https://xdp.network/api/fleet/agent.sh | bash -s -- <enroll_token>
The daemon installs as a systemd service and checks in within seconds — the modal polls until the new server appears, and from then on it reports every 15 seconds. Any signed-in account can enroll a server; you do not need to own a product first. Enrolled servers appear on the overview and on the Health Monitor product page, which lists every server with its status and score ring.
What the daemon reports
Every heartbeat (15s) sends one bundle:
- Facts — hostname, OS, kernel, architecture, CPU model and cores, total memory, virtualization kind (and whether the host can create VMs), cloud provider, uptime, public IP and the daemon's own version.
- A sample — CPU %, load averages, memory (with a used/cached/buffers/free breakdown), swap, per-disk usage with inode % and read/write throughput, per-NIC throughput plus error/drop counters, TCP connections, process count, CPU temperature, per-core busy % and clock speed, and the top processes by CPU and RSS.
- VMs — qemu/lxc/kvm guests discovered on the host.
- Events — OOM kills, failed services, reboots, disk pressure, cgroup CPU throttling, zombie process hordes and daemon lifecycle notes.
Samples are kept as 1-minute rows for 7 days and as hourly rollups for 90 days; events are kept for 30 days.
The health score
Each server gets a score from 0 to 1000, recomputed server-side from the recent sample window plus the last 24 hours of events. Instead of judging one instant, the score measures sustained stress: each component is the p80 of roughly the last 20 minutes of samples, so a one-sample spike barely moves the score while a 20-minute grind does.
| Component | Weight | What drags it down |
|---|---|---|
| CPU | 20% | Sustained high CPU %, high load-per-core, sudden spikes |
| Memory | 20% | Sustained high memory use, swap pressure |
| Disk | 20% | A mount filling up, inode exhaustion |
| Network | 10% | NIC error/drop counters rising over the window |
| Stability | 20% | Critical and warning events in the last 24h |
| Freshness | 10% | Late or missing heartbeats |
A trend modifier compares the recent half of the window with the previous half: rising stress subtracts a small penalty, easing stress adds a small bonus. A server with no heartbeat for over two minutes is offline and its score is capped at 50. Scores read as healthy (800+), strained (500–799) and critical (below 500).
The header card on the server page shows the score ring, one mini-bar per component (hover for its weight) and a Why this score list naming the exact pressures — for example "sustained CPU 92% for ~20m" or "2 OOM kills in 24h".
The server page
Click a server to open its page (/dashboard/fleet/<id>). The page polls every 15
seconds, so what you see tracks the daemon.
- Overview — the host-facts card (OS, kernel, CPU, virtualization, uptime, daemon version, and the update button covered below), a live-sample card with usage bars and NIC error/drop badges, a segmented memory-breakdown bar, a per-core CPU heat strip (one cell per logical core — hover for the exact busy %, clock speed and socket), and a top-processes table.
- Products — every product attached to the server (daemon, firewall installs, tunnel endpoints, optimizer runs, benchmarks) with state and a Manage link, plus one-click installs for the server-eligible products on your account. Installs queue as fleet jobs and start on the next heartbeat; OpenShield-XDP installs through its own licensed wizard instead. The Server actions card queues daemon-level operations: Restart daemon (reporting resumes within ~30s), Re-enroll (mints a fresh single-use enroll command), and Run command (an arbitrary script as root — staff accounts only, audit-logged). Offline servers run queued actions when they check back in.
- Resources — time-series charts over 1h/24h/7d: CPU, per-core CPU (average and busiest), memory, memory available, swap, disk, disk I/O, load, processes and network in/out, each with avg · p95 · peak baselines, plus an hourly bandwidth usage card.
- Timeline — one chronological feed of fleet events, attack transitions, jobs, OpenShield installs, and optimizer and benchmark runs.
- VMs — the guests discovered on the host (name, kind, status, CPU, memory, uptime). Enroll a hypervisor (Proxmox, KVM, VMware) and its guests appear automatically.
- Events — the server's raw event timeline with severity and kind badges, newest first, kept for 30 days.
Benchmarks
The Benchmark tab runs a one-shot hardware benchmark, measured live on the box — never simulated. Click Run benchmark (or the compact Run button in the header chip); the daemon picks the job up on its next heartbeat and the tab streams a live console. One run can be active per server, with a cap of 10 runs per server per day.
The agent measures CPU (single- and multi-thread), disk (4k random and sequential read/write) and network (download bandwidth against multiple endpoints). Each section is scored 0–100 against modern reference hardware and weighted into the total: CPU 30%, disk 30%, network 25%, stability 15% (stability is multi-core scaling efficiency). A section that cannot run reports nulls and its weight redistributes.
Finished runs carry a hardware fingerprint (a shortened sha256 of the machine identity) and a verified badge when the built-in consistency checks pass — tamper-evidence, not proof. You can share a run with a read-only public link — temporary (expires after 7 days) or permanent, revocable at any time — and compare two of your runs, or one run against a pasted share link, with per-section deltas.
Update the daemon
The daemon reports its version with every heartbeat, and the Overview tab compares it against the latest build: when they match you see a daemon up to date badge, and when they don't an Update daemon button appears, showing the version it will update to. Clicking it queues a self-update — the server pulls the latest build and restarts within about a minute. Daemons too old to report a version count as outdated.
Remove a server
Open the server card's menu on the Health Monitor page and choose Remove server. You get two modes:
- Graceful (default) — an uninstall job is queued; the daemon wipes its own service, binary, config and logs on its next heartbeat, and the row disappears when it acknowledges.
- Force delete immediately — skips the self-uninstall and deletes the row at once; the daemon's token simply stops working. Use this when the server is already gone or has been reinstalled.
Next steps
- Alerts — get notified when a server goes offline, drops below a score, or comes under attack
- Server shows offline
- REST API v1 — servers and benchmarks over the public API
- Dashboard overview