Real-time VPS monitoring with Netdata (and when to add Prometheus)
When a VPS misbehaves, minute-resolution graphs from a cloud provider console rarely tell you what happened. A CPU spike that lasts eight seconds, a burst of disk latency during a cron job, or a short-lived memory balloon from a runaway worker all disappear when data is averaged into one-minute buckets. Netdata takes the opposite approach: it collects thousands of metrics at per-second resolution and renders them in a live dashboard you can open in a browser. This article covers the one-line install, what you actually get out of the box, how to keep the dashboard off the public internet, how alerts work, the resource footprint, and the point at which you should reach for Prometheus and Grafana instead.
Installing the agent
Netdata ships an official installer, kickstart.sh, that detects your platform, prefers native binary packages, and falls back to a static build or a local compile when needed. The two forms below are equivalent; pick the one whose download tool you have installed.
wget -O /tmp/netdata-kickstart.sh https://get.netdata.cloud/kickstart.sh && sh /tmp/netdata-kickstart.sh
curl https://get.netdata.cloud/kickstart.sh > /tmp/netdata-kickstart.sh && sh /tmp/netdata-kickstart.sh
By default the installer also drops netdata-updater.sh into cron.daily so the agent updates itself nightly. If you would rather pin versions and update on your own schedule, pass --no-updates to the script. Full flag documentation lives in the Linux installation guide.
Once the script finishes, the agent starts immediately and begins serving its dashboard on port 19999. Do not open that port in your firewall yet; the next sections explain why.
What per-second metrics you get
Without any configuration, Netdata auto-detects what is running on the host and starts charting it at one-second granularity. On a typical VPS that means:
- System: per-core CPU utilization split by user, system, iowait, and steal; load average; context switches and interrupts.
- Memory: used, cached, and available RAM; swap activity; page faults; and out-of-memory events.
- Disk: throughput, IOPS, average request latency, and queue depth per block device.
- Network: bandwidth, packets, errors, and drops per interface, plus per-socket and per-protocol breakdowns.
- Applications: auto-detected collectors for common services such as Nginx, MySQL or MariaDB, PostgreSQL, Redis, and Docker containers, plus a per-process resource tree.
The value of per-second resolution is that transient events remain visible. An iowait spike that only exists for three seconds is a single blip on a Netdata chart and completely invisible on a one-minute average. The getting started guide walks through the dashboard layout.
Do not expose port 19999 publicly
The most common Netdata mistake is opening 19999 to the world so the dashboard is reachable at http://your-vps-ip:19999. The agent's built-in web server is meant for local access, and an unauthenticated dashboard exposes detailed internal telemetry about your host to anyone who scans the port. The correct pattern is to bind the agent to localhost and put a reverse proxy in front of it that terminates TLS and enforces authentication.
Bind the agent to the loopback interface only. Use the agent's own editor so the change lands in the right file:
cd /etc/netdata
sudo ./edit-config netdata.conf
In the [web] section set the bind address:
[web]
bind to = 127.0.0.1:19999 localhost:19999
Restart the agent and confirm it is no longer listening on a public interface:
sudo systemctl restart netdata
sudo ss -ltnp | grep 19999
You should see the socket bound to 127.0.0.1 only. Keep 19999 closed in your firewall regardless; binding to localhost and firewalling the port are complementary, not redundant. The securing agents guide documents the binding options in full.
Reverse proxy with authentication
Put Nginx in front of the agent so access requires a password and, in production, runs over HTTPS. A minimal server block that proxies to the local agent and enforces HTTP basic auth looks like this:
upstream netdata {
server 127.0.0.1:19999;
keepalive 1024;
}
server {
listen 80;
server_name netdata.example.com;
auth_basic "Protected";
auth_basic_user_file /etc/nginx/passwords;
location / {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://netdata;
proxy_http_version 1.1;
proxy_pass_request_headers on;
proxy_set_header Connection "keep-alive";
proxy_store off;
}
}
Create the credentials file the proxy references:
printf "youruser:$(openssl passwd -apr1)" > /etc/nginx/passwords
Terminate TLS on this server block with a certificate from your CA of choice, and restrict the proxy to trusted networks where possible. Configurations for Apache and Caddy are covered in the reverse proxy documentation.
Alerts and notifications
Netdata ships with a health engine and a set of pre-built alarms, so out of the box you already get alerts on conditions like sustained high CPU, low available RAM, disk filling up, and network errors. Alarm definitions live under /etc/netdata/health.d/, and you edit them with the same helper used above:
cd /etc/netdata
sudo ./edit-config health.d/cpu.conf
After changing an alarm you do not need to restart the agent. Reload the health engine so collection is not interrupted:
sudo netdatacli reload-health
To route alerts somewhere useful, configure the notification methods, which include email, Slack, Discord, and Telegram among others:
sudo ./edit-config health_alarm_notify.conf
Details on alarm syntax, thresholds, and hysteresis are in the alert configuration reference.
Resource footprint
Per-second collection sounds expensive, and the honest answer is that it is heavier than a minute-interval agent, mostly because of the in-memory time-series database that powers the live charts. In practice the CPU cost is modest. Netdata's own documentation describes the agent as designed to run with low overhead, and their guidance targets under one percent of a single CPU core for the collection work on a typical host.
The main tunables are retention and collection frequency, both in netdata.conf:
- Update frequency: the
update everysetting controls the collection interval. Leaving it at 1 gives you per-second resolution; raising it reduces CPU and memory at the cost of granularity. - Retention: the database engine tiers control how much history is kept and how much RAM and disk it consumes. Shorter retention means a smaller footprint.
This makes the agent a reasonable fit for a modest VPS, where you want visibility without dedicating a large slice of the box to monitoring. If memory is tight, trim retention first; it is the largest lever.
When to graduate to Prometheus and Grafana
Netdata is excellent for real-time, single-node troubleshooting: you open the dashboard, watch a live problem, and drill into per-second detail. It is less suited to some jobs that a metrics pipeline handles better. Consider adding Prometheus and Grafana when:
- You run many nodes and want a single place to query and correlate metrics across the whole fleet rather than opening one dashboard per host.
- You need long-term history measured in months or years, with a storage and downsampling model built for that horizon.
- You want custom dashboards and ad-hoc queries using a query language (PromQL) and mixing metrics from many exporters into one panel.
- Alerting must be centralized across services through Alertmanager rather than configured per agent.
You do not have to choose. Netdata can expose its metrics in Prometheus format, so a common pattern is to keep Netdata on each VPS for live, high-resolution troubleshooting while Prometheus scrapes a subset of metrics for long-term storage and Grafana builds the fleet-wide dashboards. Start with Netdata alone; add the pipeline when the scale or retention requirements above actually appear, not before.
Wrap-up
Netdata gets you from zero to a per-second, auto-discovered dashboard in one command, which makes it hard to beat for diagnosing a live problem on a single server. The one rule you must not skip: keep the agent bound to localhost, put a reverse proxy with authentication and TLS in front of it, and never expose port 19999 to the internet. Once you are running more than a handful of nodes or need long-horizon history, layer Prometheus and Grafana on top rather than replacing what already works.