For lightweight server monitoring on one VPS or a handful of them, the honest shortlist is short, and the right pick depends on the question you are asking. If you want to know whether your boxes are healthy, use Beszel. If you want to know whether users can open your site, use Uptime Kuma. For a VPS fleet panel across regions use Nezha, for one box right now use Glances, and for per-second detail during an incident use Netdata. Most people need one of these, sometimes two, rarely a full observability stack.
Disclosure: we build Termalin, which is one of the options below. The open-source tools are described from their public docs, checked October 15, 2026, and several of them win rows outright.
This post covers what each tool watches, what “lightweight” really costs, and the parts the top results skip: who watches the monitor when the VPS itself dies, how to keep alerts from becoming noise, a small fallback script, and how to monitor a box that has no open port.
The short answer: which tool for which question
- Beszel — “are my boxes OK?” A hub plus a tiny agent per server. Host metrics and Docker stats, with alerts to Telegram and more. The lightweight default.
- Netdata — “what happened in that exact second?” Per-second metrics and deep per-process detail. The most data-hungry here, which is the point.
- Uptime Kuma — “can the outside world reach my service?” HTTP, TCP, ping and DNS checks with status pages. It does not watch CPU, memory or disk.
- Nezha — “how is my fleet of VPS doing, across providers and regions?” A probe-style panel with a web terminal, popular for multi-region setups.
- Glances — “what is this one box doing right now?” A live view, like
htoporbtopwith more on screen. Not an alerting tool. - Termalin — “watch my servers and alert me, with nothing extra to install.” Monitoring rides on an SSH access connector you already have. Paid, and with real limits (below).
What “lightweight” really means for server monitoring
“Lightweight” is usually quoted as the agent’s memory, which is the wrong number. Count the whole thing:
- The agent on each box — usually a single compiled binary, small by design.
- The hub or dashboard — this is where the weight lives: a web app, often a database, running somewhere that stays up.
- Open ports — every listening port is attack surface you now own.
- Containers and services to patch — one more thing to keep updated, forever.
By that measure, Beszel (one agent + one hub container) and Uptime Kuma (one container) are genuinely light. Netdata’s per-second collection is the most resource-hungry of this group on both CPU and storage — that is the trade for its resolution. And the classic “big stack” — Prometheus plus node_exporter plus Grafana plus Alertmanager — is four moving parts to deploy, secure and patch. It is excellent, but it is not lightweight, and for one to twenty servers it is usually more than the job needs.
The contenders
Beszel
A hub (built on PocketBase) plus a small Go agent on each server. The agent can run two ways: the hub connects to it over SSH on port 45876, or the agent dials out to the hub over a WebSocket with a token — the second mode needs no inbound port and works behind NAT. It reads host metrics and Docker container stats, and alerts on CPU, memory, disk, bandwidth, temperature and up/down status, to 25+ channels including Telegram and ntfy. MIT-licensed; the docs are on v0.21 at the time of writing. This is the one to beat for plain “are my boxes healthy.”
Netdata
Per-second metrics with a dense live dashboard and a lot of automatic per-process and per-service detail. The agent is free and runs unlimited on your own hosts, serving its own dashboard locally. Netdata Cloud, which ties agents together and routes notifications, is free on the Community tier up to 5 connected nodes; past that it is Homelab at $90/year (unlimited, fair use) or Business at $4.50/node/month billed annually. Reach for it when you are debugging a spike and a one-minute average is too coarse.
Uptime Kuma
The self-hosted uptime monitor: HTTP(s), TCP, keyword, ping, DNS, push and Docker-container checks, 90+ notification services, and public status pages. Around 92k GitHub stars, MIT. The one thing to be clear about: Uptime Kuma does not collect host CPU, RAM or disk — it watches whether services respond, from the outside. That makes it the natural partner to a host-metrics tool, not a replacement for one, and the usual answer to “a self-hosted Uptime Kuma alternative” is really “pair Kuma with Beszel.”
Nezha
A dashboard plus an agent that reports system status, runs HTTP/TCP/ping checks and certificate-expiry checks, raises alerts, runs scheduled tasks, and gives you a web terminal to each host. The agent dials out to the dashboard. It is the de facto VPS “probe” panel in the Chinese- and Korean-speaking communities, and it shines when you have many small VPS across different providers and regions and want one page for all of them.
Glances (and htop/btop)
Glances is a live, single-box view: CPU, memory, disk, network, processes and more on one screen, over SSH or an optional local web page. Like htop and btop, it answers “what is this box doing right now” and nothing more — there is no history and no real alerting. Keep it in your toolbox for hands-on debugging; do not expect it to page you.
The comparison table
| Tool | What it watches | Alerts & channels | Needs an inbound port? | Cost | Best at |
|---|---|---|---|---|---|
| Beszel | Host metrics + Docker stats | CPU/mem/disk/bandwidth/temp/status; 25+ channels (Telegram, ntfy) | No in WebSocket mode; yes (45876) in SSH mode | Free, MIT (self-host) | Lightweight fleet health |
| Netdata | Host metrics, per second | Built-in alarms; notifications via agent or Cloud | Local dashboard on 19999; Cloud link is outbound | Agent free; Cloud free ≤5 nodes, then $90/yr or $4.50/node/mo | High-resolution incident detail |
| Uptime Kuma | Uptime: HTTP/TCP/ping/DNS/push/containers (no host metrics) | 90+ services; status pages | Reaches out to targets; you host its dashboard | Free, MIT (self-host) | External uptime + status pages |
| Nezha | System status + HTTP/TCP/ping + cert expiry | Alerts, scheduled tasks; web terminal | Agents dial out to the dashboard | Free (self-host) | Multi-region VPS panel |
| Glances | One box, live | Not an alerting tool | Local; optional web view | Free (self-host) | A single box, right now |
| Termalin | Host metrics over the Connector (no second agent) | Default-threshold alerts; email, iOS push, Telegram, webhook | No — the Connector is outbound only | Pro $10/mo or $8/mo yearly; Team $15/user | Health + alerts with nothing to install |
Who watches the monitor when the VPS dies?
Here is the gap most comparisons skip. If your hub or dashboard runs on the same VPS it is watching, it dies with that VPS — and a dead server cannot tell you it is dead. “Server offline” is exactly the alert you most want, and it only works from a second vantage point.
Three ways to cover it:
- A second, cheap VPS in another location running the external check. This is what we do: we run Uptime Kuma on a separate low-cost VPS whose only job is to notice when the main boxes stop answering.
- A free external checker that pings your public endpoints from outside your network.
- A hosted service whose “is it up?” logic runs on infrastructure that is not yours, so it survives your box going down.
Whatever you pick, the rule is simple: the thing that detects “offline” must not live on the machine that goes offline.
Alerts that don’t train you to ignore them
A monitor that pages you ten times an hour gets muted within a week, and then it is worse than nothing. Out-of-the-box tools tend to be either silent until you write rules, or chatty until you tune them. Either way the work is the same:
- One message when a problem opens, one when it clears — not a reminder every five minutes.
- Grouping — several problems in the same minute arrive as one message; a genuinely critical one still goes straight through.
- No same-day repeats for the same issue, unless it is critical and persists.
- A quiet first day, so a newly watched box does not dump every pre-existing failed unit and expired certificate on you at once.
- Per-alert, per-server mute, so one noisy check does not force you to silence everything.
And pick thresholds that mean something: disk at 90% warning and 95% critical, or forecast to fill within a day; inodes running out; an out-of-memory kill; a failed systemd unit; a TLS certificate 14 days from expiry (critical at 3); and “offline” only after a few minutes, so a reboot is not an alarm. Whatever tool you choose, this tuning is the real work of monitoring — more than picking the tool.
The ten-line fallback: a disk-space alert to Telegram
Before you deploy anything, you can cover the single most common VPS failure — a full disk — with cron, df and curl. This is the answer to “disk space alert script linux” and “server monitoring telegram alerts” when you do not want a dashboard yet.
Keep the secrets out of the script. Read them from the environment:
#!/usr/bin/env bash
# disk-alert.sh — warn via Telegram when a filesystem is too full.
set -euo pipefail
: "${TELEGRAM_BOT_TOKEN:?set TELEGRAM_BOT_TOKEN}"
: "${TELEGRAM_CHAT_ID:?set TELEGRAM_CHAT_ID}"
threshold="${DISK_THRESHOLD:-90}"
df -x tmpfs -x devtmpfs --output=pcent,target | tail -n +2 | while read -r pct mount; do
used="${pct%\%}"
[ "$used" -ge "$threshold" ] || continue
curl -fsS --max-time 15 \
--data-urlencode "chat_id=${TELEGRAM_CHAT_ID}" \
--data-urlencode "text=$(hostname): ${mount} is ${used}% full" \
"https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" >/dev/null
done
Put the real values in a root-only file, never in the script or the crontab:
# /etc/disk-alert.env — chmod 600, owned by root
export TELEGRAM_BOT_TOKEN=123456789:replace-with-your-bot-token
export TELEGRAM_CHAT_ID=987654321
export DISK_THRESHOLD=90
Then run it every fifteen minutes with cron. Save this line as /etc/cron.d/disk-alert (this format, with a user name, is for files in /etc/cron.d/):
*/15 * * * * root . /etc/disk-alert.env && /usr/local/bin/disk-alert.sh
It repeats every fifteen minutes while the disk stays full. For a last-resort alert that is on purpose; if it is too loud, run it hourly instead.
Make a bot with @BotFather, send it one message so it can reply to you, and read your chat_id once from getUpdates. That is the whole thing: no agent, no port, no dashboard. It will not scale past a few boxes, but it will catch the failure that takes most VPS down.
Monitoring behind NAT, CGNAT, or no open ports
A box behind NAT or CGNAT cannot accept an inbound connection, so any monitor that works by connecting to the box is out. The ones that work all share one shape — the box reaches out:
- Beszel in WebSocket mode: the agent dials out to the hub, no inbound port. (SSH mode needs inbound
45876, so avoid it here.) - Netdata: the agent’s link to Netdata Cloud is outbound.
- Uptime Kuma: use a push monitor — the box calls a Kuma URL on a schedule, and Kuma alerts when the calls stop.
- Termalin: the Connector is outbound-only and never listens on a port.
The general technique — and why “let it reach out” is the only safe answer for a private box — is in SSH behind NAT without port forwarding, and the home-lab version is in SSH into a home NAS or server.
Where Termalin fits — and where it doesn’t
Termalin’s angle is different from the tools above: it does not add a monitoring agent at all. If a server already has a Termalin Connector — the same outbound, no-inbound-port agent you use for keyless SSH access — then it is already monitored. There is no second agent: once a minute Termalin runs a few read-only commands (/proc, df, ps and similar) over the connection the Connector already holds. The cost to the box is a few milliseconds of CPU and about a kilobyte a minute.
What it reads is the usual health picture: CPU (including iowait and steal), load and pressure, memory and swap, disk space and inodes, disk and network I/O, sockets and open files, processes, containers, failed services, failed SSH sign-ins, pending security updates, listening ports, and TLS certificates with days to expiry. Alerts work with default thresholds and no rules to write, and they are built to stay quiet: once in, once out, grouped, no same-day repeats, a calm first day, and per-alert mute. They go to email, iOS push, Telegram (one tap to connect the bot) and a webhook that Slack and Discord accept, signed with HMAC-SHA256. History is 90 days on Pro and two years on Team.
Because an AI assistant can read the same data over Termalin’s hosted MCP endpoint (server_metrics and alerts_list), you can also just ask “how are my servers doing?” in Claude or ChatGPT and get the answer from collected data. In the web terminal, select an error in the output and choose Explain the selection: the assistant writes a short plain-language diagnosis and ends with a few read-only check commands that a button types into the session for you. The full picture is on the server monitoring page.
Now the honest limits, because the open-source tools beat it on several of them:
- No external uptime checks and no status pages. This is a host-metrics-and-alerts tool, not an uptime monitor — Uptime Kuma still complements it.
- No log collection and no custom metrics. It is not a Grafana/Prometheus replacement.
- Dashboards are in the web cabinet only for now, not the desktop app — though the desktop app does show a connected host’s CPU, memory and disk live in its status bar and in the watch grid.
- Not end-to-end encrypted — these numbers are stored in a form the service can read, because it has to read them to draw charts and raise alerts.
- Not on the Free plan. It needs a Connector, which is part of Pro ($10/month, or $8/month billed yearly — $96/year) and Team ($15 per user), with a 14-day Pro trial that needs no card.
If “free and self-hosted” is a hard requirement, Beszel or Uptime Kuma is your answer, and that is a fair call. Termalin’s case is narrower: you already use it for SSH access, and you would rather not stand up and babysit a separate monitoring stack to get health charts and sane alerts.
Picks by situation
- One hobby VPS. Beszel for health, or just the cron script above if all you fear is a full disk. Add Uptime Kuma later if you run a public site.
- 5–20 VPS across providers (Hetzner, Contabo, Hostinger, a droplet or two). Beszel for metrics plus Uptime Kuma for uptime, with the Kuma instance on a separate box. If you prefer one panel with a web terminal, Nezha. If you already run Termalin for SSH, turn its monitoring on and skip the extra stack.
- A homelab behind CGNAT. Anything outbound-only: Beszel in WebSocket mode, Netdata to Cloud, or a Kuma push monitor — see the behind-NAT guide.
- “I want my AI assistant to answer ‘how are my servers’.” That is the Termalin case: the same data a human sees, read by the agent over MCP.
FAQ
Is Netdata free? The agent is free and runs unlimited on your own hosts, with its own local dashboard. Netdata Cloud’s Community tier is free up to 5 connected nodes; beyond that it is Homelab at $90/year or Business at $4.50/node/month billed annually.
Does Uptime Kuma monitor CPU, memory or disk? No. Uptime Kuma checks whether services respond — HTTP, TCP, ping, DNS, containers and push — from the outside. For host CPU, RAM and disk, pair it with Beszel, Netdata or Termalin.
Beszel vs Netdata — which is lighter? Beszel. It is one small agent per box plus a single hub. Netdata collects per second and is the most resource-hungry of this group; you choose it for resolution, not for being light.
What is the best free VPS monitoring with Telegram alerts? For host health, Beszel sends to Telegram and is free to self-host. For uptime, Uptime Kuma does too. For a no-install stopgap, the cron + curl script above sends straight to Telegram with nothing running in the background.
How do I monitor a VPS behind NAT or with no open ports? Use a tool where the box reaches out: Beszel in WebSocket mode, the Netdata agent to Cloud, a Kuma push monitor, or a Termalin Connector. None of them needs an inbound port. See SSH behind NAT without port forwarding.
Termalin is a cross-platform SSH client; on Pro and Team every server that has a Connector is monitored with charts and default-threshold alerts, and nothing extra is installed on the box — see server monitoring or download it.