How to Monitor a Linux Server Without Paid Tools
You do not need a paid monitoring suite to know what your Linux server is doing. Every distribution already ships with tools that answer the daily questions: is the CPU overloaded, is the disk struggling, why did a service die, who is connected. This guide walks through those tools with concrete thresholds and ends with a five-minute cron healthcheck that alerts you on Telegram or by email when your site goes down.
CPU and memory: top and htop
top is preinstalled everywhere; htop is easier to read and worth installing:
apt install htop # Debian/Ubuntu dnf install htop # RHEL/Alma/Rocky htop
Read the load average first: three numbers showing the 1, 5 and 15 minute averages. The rule is to compare load to your core count, which nproc prints. Load 4.0 on a 4-core server means the CPU is fully busy. Sustained load above the core count means processes are queueing and everything slows down. Load 2.5 on 8 cores is nothing; load 2.5 on 1 core is a problem.
Two more fields matter. wa (iowait) in the CPU line is the share of time the CPU spends waiting for disk: consistently above 10 percent means your bottleneck is storage, not CPU, so move on to iostat. For memory, watch the RES column per process (real RAM used, unlike the mostly meaningless VIRT) and judge by available memory, not free memory: Linux deliberately uses spare RAM for disk cache and releases it on demand.
Disk I/O: iostat and what await means
iostat lives in the sysstat package:
apt install sysstat iostat -x 5
This prints extended stats every 5 seconds. Ignore the first block, it is an average since boot. Two columns matter:
- r_await / w_await: average time in milliseconds a read or write request takes, including time spent waiting in the queue. This is the single best "is my disk struggling" number.
- %util: how busy the device is. 100 percent on a modern SSD is not automatically fatal, since it serves requests in parallel, but combined with high await it confirms saturation.
Reference points for await: NVMe should sit under 1 ms, SATA SSD 1 to 5 ms, spinning disks 5 to 15 ms. Sustained tens of milliseconds mean storage is the bottleneck: either a process is hammering the disk (find it with iotop or pidstat -d 5) or the volume is genuinely too slow for the workload.
Disk space: df, du and the 80 percent rule
df -h shows usage per filesystem. The working rule: act at 80 percent. Beyond that, databases and log-heavy services run out of headroom fast, and a completely full root partition breaks things in ugly ways: services cannot write PID files, upgrades fail halfway, sometimes you cannot even log in cleanly.
df -h df -i
df -i checks inodes: a partition can be full with gigabytes to spare if millions of tiny files (sessions, cache, mail queue) have eaten all inodes. To find what actually consumes space, descend with du:
du -xh --max-depth=1 / | sort -h | tail -15 du -sh /var/log/* | sort -h | tail -10
The usual suspects are /var/log, old backups and the systemd journal. Cap the journal so it stops growing:
journalctl --vacuum-size=500M
Logs and connections: journalctl and ss
When something misbehaves, ask the journal before guessing:
journalctl -p err -b journalctl -u nginx --since "1 hour ago" journalctl -f journalctl -k --grep=oom
The first command lists every error since boot, the second scopes to one service, the third follows live. The last one searches kernel messages for the OOM killer: if a process vanished without a trace, the kernel probably killed it for eating all RAM, and this is where that gets recorded.
For network questions, ss replaced netstat:
ss -tulpn ss -s ss -tn state established | wc -l
ss -tulpn shows every listening socket and the process behind it. Run it after each deploy; anything you do not recognize deserves investigation. ss -s prints totals, and counting established connections over time tells you whether a spike is real traffic or connections stuck open by a broken client or a slow backend.
A cron healthcheck with Telegram or email alerts
You can build basic uptime alerting yourself in five minutes. Create a bot via @BotFather in Telegram, copy the token, send the bot one message, then get your numeric chat id:
curl -s "https://api.telegram.org/bot$TOKEN/getUpdates"
Save this as /usr/local/bin/healthcheck.sh and make it executable:
#!/bin/bash
URL="https://example.com/health"
TOKEN="123456:AA...your-bot-token"
CHAT="987654321"
CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 "$URL")
if [ "$CODE" != "200" ]; then
curl -s "https://api.telegram.org/bot$TOKEN/sendMessage" \
-d chat_id="$CHAT" -d text="ALERT: $URL returned HTTP $CODE"
fi
Then schedule it every 5 minutes:
*/5 * * * * /usr/local/bin/healthcheck.sh
Prefer email? Replace the Telegram call with echo "$URL returned $CODE" | mail -s "Server alert" you@example.com, which needs mailutils and a configured MTA. The same script can also watch the 80 percent disk rule: read usage with df -P / | awk 'NR==2 {print $5}' and alert when it crosses the line.
One honest caveat: run the check from a different machine than the one you monitor. A server that is down cannot report itself. The cheapest second VPS or a Raspberry Pi at home is enough.
When to graduate to real monitoring
The manual toolkit stops being enough at a predictable point. Move to a proper stack when any of these become true:
- You run more than two or three servers and log into each to check them.
- You need history: htop cannot answer "was the disk slow yesterday at 14:30".
- You want alerts on trends, like a disk that will hit 80 percent in three days, not just up or down.
- Someone other than you needs to see the state of the system.
The standard free self-hosted answer is Prometheus with node_exporter and Grafana, or Zabbix if you prefer one integrated system; Netdata gives an instant per-second view of a single machine. All are free software with a real cost in setup and maintenance time, so adopt them when the manual checks start eating hours.
Also be honest about what the numbers say. If load sits pinned above your core count or await keeps climbing on a busy disk, the fix is more hardware, not more graphs: compare your figures against our VPS plans before spending a week on tuning. And if you would rather not read graphs at 3 AM at all, our IT support team can take over monitoring and incident response.