VPS Monitoring That Catches Problems in Under 60 Seconds

A VPS does not fail loudly. It fails at the margin: steal time creeping from 0.4% to 6%, iowait climbing past 20% of wall clock, free memory sliding under the page-cache floor until the OOM killer picks a victim. By the time `uptime` shows a load of 40, you have already been down for minutes. The targets below come from production KVM nodes on 2 vCPU / 4 GB instances, and every one of them is measurable with tools already in your distribution’s base repositories.

The Four Metrics That Actually Predict Failure

MetricHealthyWarningAct nowCommand
steal (from /proc/stat)< 1%1–4%> 5%`top -bn1 | head -3`
iowait< 5%5–15%> 20%`iostat -x 5`
Available memory> 25% RAM10–25%< 10%`free -m`
Disk await (NVMe)< 1 ms1–5 ms> 10 ms`iostat -x 5`

Steal is the single highest-signal number on a VPS, because it measures time your vCPU wanted to run but the hypervisor gave to somebody else. On a dedicated-core plan it should sit near zero. On an overcommitted host it will wander. Read it from `/proc/stat` field 8 in `cpu` line — it is cumulative jiffies, so you need the delta between two samples, not the raw value.

# Steal time delta over 10 seconds, as a percentage
S1=$(awk '/^cpu /{print $9}' /proc/stat); T1=$(awk '/^cpu /{print $2+$3+$4+$5+$6+$7+$8+$9+$10}' /proc/stat)
sleep 10
S2=$(awk '/^cpu /{print $9}' /proc/stat); T2=$(awk '/^cpu /{print $2+$3+$4+$5+$6+$7+$8+$9+$10}' /proc/stat)
echo "steal: $(awk -v s=$((S2-S1)) -v t=$((T2-T1)) 'BEGIN{printf "%.2f%%", 100*s/t}')"

Sample Everything at 15 Seconds, Keep 30 Days

Anything coarser than a 15-second scrape interval will smooth away the spikes that matter — a 40-second I/O stall disappears inside a one-minute average. Prometheus with node_exporter is the standard stack, and it fits in roughly 180 MB RSS plus disk for a single node.

# node_exporter + Prometheus, no Docker required
curl -LO https://github.com/prometheus/node_exporter/releases/latest/download/node_exporter-1.8.2.linux-amd64.tar.gz
tar xzf node_exporter-*.tar.gz && sudo install -m755 node_exporter-*/node_exporter /usr/local/bin/
sudo useradd -rs /bin/false node_exporter

sudo tee /etc/systemd/system/node_exporter.service >/dev/null <<'EOF'
[Unit]
Description=Prometheus node exporter
After=network-online.target
[Service]
User=node_exporter
ExecStart=/usr/local/bin/node_exporter --collector.systemd --collector.processes
Restart=always
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable --now node_exporter

Point Prometheus at `localhost:9100` with a 15s `scrape_interval` and a 30d retention cap. On a 2 GB VPS, budget about 400 MB of disk per month per node — trivial, and the difference between diagnosing an incident in four minutes versus four hours.

Alert on Rates, Not on Gauges

A static threshold of `node_load1 > 4` on a 2-vCPU box pages you constantly and trains you to ignore alerts. Use a sustained-rate expression instead, so you only hear about conditions that persist:

- alert: VPSIOStall
  expr: rate(node_cpu_seconds_total{mode="iowait"}[5m]) > 0.20
  for: 10m
  annotations:
    summary: "iowait above 20% for 10 minutes on {{ $labels.instance }}"

- alert: VPSMemoryPressure
  expr: (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) < 0.10
  for: 5m

- alert: VPSDiskFillProjection
  # fires when the current fill rate exhausts the disk within 24h
  expr: predict_linear(node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"}[6h], 86400) < 0
  for: 30m

`predict_linear` is the alert most people never configure and the one that saves the most downtime. A disk at 60% with a 2 GB/hour growth rate is a tomorrow-morning outage; a disk at 88% that is flat is not. The first alert above is essential arithmetic, and it arrives with 24 hours of warning.

Fast Local Instrumentation When You Are Already Logged In

  • atop — `sudo apt install atop; sudo atop -w /var/log/atop/atop_%Y%m%d -a 60 1440` writes 60-second snapshots for 24 hours. `atop -r file -b 14:03` lets you rewind to the exact minute of an anomaly.
  • pidstat — from sysstat, gives per-process CPU, fault, and I/O attribution: `pidstat -dru -h 5 12`.
  • sar — sysstat’s historical recorder. `sar -q -f /var/log/sysstat/sa$(date +%d)` prints the load and queue history for today.
  • iotop -oPa — shows only processes with active I/O, which is how you find the `updatedb` or backup job eating your write bandwidth at 03:00.

For a web-facing VPS, add one application-level probe: `curl -o /dev/null -s -w ‘%{time_starttransfer}\n’ https://example.com/ping` on a 30-second loop, written to a textfile collector. TTFB is the number your users feel, and it will diverge from kernel metrics the moment a database query starts doing a filesort.

The Three-Minute Triage When an Alert Fires

When the alert lands, you want a fixed order of operations rather than improvisation. Run this sequence top to bottom; each step either clears a layer or identifies it as the cause, and it takes under three minutes:

# 1. What is the machine's own description of the problem?
uptime                                   # load vs nproc
free -m                                  # MemAvailable, swap used
# 2. Is it CPU contention, I/O, or memory? One command, five samples:
vmstat 1 5                               # r, b, si, so, us, sy, wa, st
# 3. If wa (iowait) is high, who is writing?
sudo iotop -oPab -d1 -n3 | head -30
# 4. If st (steal) is high, it is not your process - stop tuning and check the host.
# 5. If us+sy is high, find the top consumer:
ps -eo pid,ppid,pcpu,pmem,rss,etime,comm --sort=-pcpu | head -12
# 6. If si/so move, memory pressure is the root cause; find the leak:
sudo smem -tk -s rss | tail -15

The ordering matters because the first two commands eliminate whole categories of cause. If `vmstat` shows `r` well below `nproc` while `wa` is above 20, you have an I/O problem and no amount of process investigation will help. If `st` is above 5, the problem is on somebody else’s vCPU and the correct action is a support ticket, not a config change.

The three internal reference points worth bookmarking before you tune anything are our VPS benchmark methodology — so you know what a healthy instance of your plan measures — plus the provider comparison with measured steal and IOPS figures. A monitoring stack is only useful when you have a baseline to compare against; those two pages give you one.

If you are tuning a small VPS and want hardware that does not fight you, our VPS provider performance tables break down CPU steal, NVMe IOPS, and RAM overcommit behaviour across the hosts we test on. Newer KVM nodes with dedicated vCPU pinning make the numbers in this article reproducible rather than aspirational. Two hosts we keep coming back to: InterServer VPS for flat-rate pricing with no RAM upcharge, and Cloudways managed cloud if you would rather not manage the kernel yourself. Compare the two against the benchmark methodology we publish before you commit.

Leave a Reply