You do not need a commercial monitoring platform to keep an eye on a small VPS. Prometheus and Grafana together form a complete, self-hosted metrics stack: Prometheus scrapes and stores time-series data, and Grafana turns it into dashboards you can actually read. Both run comfortably on a 1-2 GB VPS, and both are free. This guide covers installation, scraping configuration, PromQL basics, and alerting for small deployments.
Monitoring is only as good as the hardware underneath it — compare VPS providers on our comparison table to ensure your plan has enough RAM for both your application and the metrics stack.
Why Prometheus Fits a Small VPS
Prometheus is a single static Go binary with no external dependencies. It uses a pull model: it fetches metrics from exporters over HTTP on a schedule you define, which means no agents need to push data and the server stays in control. A default install with a few exporters uses roughly 150-250 MB of RAM, leaving plenty of room for application processes on a 2 GB plan. Because everything is plain HTTP and YAML, the whole stack is trivial to version in Git and reproduce on a new host.
Installing Prometheus and node_exporter
Download the latest release from the official site, extract it, and run it as a dedicated system user. node_exporter exposes host metrics such as CPU, memory, disk, and network:
sudo useradd --no-create-home --shell /bin/false prometheus
wget https://github.com/prometheus/prometheus/releases/download/v2.53.0/prometheus-2.53.0.linux-amd64.tar.gz
tar xzf prometheus-2.53.0.linux-amd64.tar.gz
sudo cp prometheus-2.53.0.linux-amd64/{prometheus,promtool} /usr/local/bin/
# node_exporter
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz
tar xzf node_exporter-1.8.2.linux-amd64.tar.gz
sudo cp node_exporter-1.8.2.linux-amd64/node_exporter /usr/local/bin/
Create systemd units for both services so they start on boot and restart on failure. node_exporter listens on port 9100 and Prometheus on 9090; bind Prometheus to localhost or put it behind a reverse proxy with authentication.
Configuring Scrape Targets
Prometheus discovers targets from a YAML configuration file. A minimal prometheus.yml for a single VPS scrapes Prometheus itself and the node exporter:
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
Add one job per exporter or application: mysqld_exporter for MySQL, postgres_exporter, blackbox_exporter for HTTP probes, and cAdvisor if you run Docker. Each is a static target line — no agents to install on other machines.
Querying Metrics with PromQL
PromQL is the query language behind every dashboard. The two patterns you will use most are rates over time and instant gauges:
# CPU usage percentage over 5 minutes
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# Memory usage
node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes
# Disk space free
node_filesystem_avail_bytes{mountpoint="/"}
Building a Grafana Dashboard
Grafana connects to Prometheus as a data source, then visualizes PromQL queries as panels. The fastest route is the official Node Exporter Full dashboard (ID 1860), which you import in two clicks. For custom panels, every query you write in PromQL becomes a panel with a threshold, a unit, and an alert attached. Grafana’s provisioning API lets you store dashboards as JSON files in Git, so your monitoring setup is reproducible. If you prefer not to manage Grafana at all, Prometheus ships with a basic expression browser, but the dashboards are what make the data actionable, and Grafana is worth the extra 50 MB of RAM.
Alerting Without the Noise
Small deployments should alert on a handful of signals: disk filling, memory pressure, host down, and high load. Define alert rules in Prometheus and let Alertmanager route them to email, Telegram, or Slack:
groups:
- name: host
rules:
- alert: HostDown
expr: up == 0
for: 5m
labels: { severity: critical }
- alert: DiskAlmostFull
expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) < 0.1
for: 10m
labels: { severity: warning }
Start with two or three rules rather than a dozen. Alert fatigue is the main reason monitoring gets ignored, and on a single VPS a disk-filling alert matters far more than a five-minute CPU blip.
Keeping the Stack Light on a Budget VPS
- Set retention to 15-30 days in Prometheus flags: –storage.tsdb.retention.time=30d.
- Scrape every 15-30s, not every 5s — fine-grained data is rarely useful after the fact.
- Run Grafana behind Nginx or Caddy with TLS and basic auth.
- Pin both services with systemd MemoryMax to cap runaway usage.
Once your dashboards are live, the last piece is knowing whether your VPS itself is sized right for the load you are measuring — see the full specs and pricing across providers to plan upgrades before you hit the ceiling.
If you prefer a managed platform where monitoring and scaling are handled for you, Cloudways offers managed VPS hosting with built-in monitoring — start with their free trial.


Leave a Reply
You must be logged in to post a comment.