Every VPS needs monitoring before it needs scaling. External uptime checks tell you when a service is unreachable. Internal health metrics tell you why it is failing before it goes down. The combination of both gives you the full picture: whether your application is online, whether your server has resources left, and whether an outage is minutes away. For developers running production workloads on a VPS, self-hosted monitoring is the difference between reacting to a 3 AM outage and preventing it entirely.

The tools you choose depend on what you are running and what you need to know. A single website needs external uptime checks. A database server needs internal metrics. A container cluster needs both, plus service-level observability. This guide evaluates the four most common self-hosted monitoring stacks for VPS workloads, explains when each fits, and shows how to set up alerting that actually wakes you up.

Why Every VPS Needs Monitoring Before It Needs Scaling

Scaling a server that you do not monitor is gambling. You are increasing resources for a problem you have not diagnosed. A common pattern is adding RAM to a server that is actually failing because of a memory leak, not because of legitimate load. Without metrics, you cannot tell the difference.

External uptime checks vs. internal health metrics

External uptime monitoring checks your services from outside the server. It sends HTTP requests to your website, TCP probes to your database port, or DNS lookups to your nameserver. If the response is missing, slow, or wrong, you get an alert. This tells you that users cannot reach your service. It does not tell you why.

Internal health monitoring runs on the server itself. It measures CPU utilization, memory pressure, disk I/O latency, network throughput, and process-level metrics. It tells you whether the server is running out of resources, whether a service is consuming more memory than expected, and whether disk space is filling up. This is the data you need to prevent an outage, not just detect one.

A complete monitoring setup uses both. External checks confirm that your service is reachable from the internet. Internal metrics explain whether the server can sustain its current load. One without the other leaves you guessing.

What happens when you monitor nothing

A typical unmonitored failure looks like this. A small VPS runs a web application and a database on the same server. Memory usage grows slowly over days because of a query cache that never expires. The Linux Out-Of-Memory (OOM) killer starts terminating processes to free RAM. At 3 AM, it kills the database process. The website returns connection errors. The first person to notice is a customer sending an email twelve hours later.

With basic monitoring, this is preventable. A memory threshold alert at 80% usage would have triggered days before the OOM killer activated. A process monitor checking whether the database service is running would have alerted the moment the process stopped. An external uptime check would have confirmed that the website was unreachable from the internet. All three signals together point to a memory problem before it becomes an outage.

Uptime Kuma: External Monitoring in Minutes

Uptime Kuma is the fastest way to add external monitoring to a VPS. It is a lightweight, open-source monitoring tool that runs as a Docker container and provides a web dashboard for checking HTTP endpoints, TCP ports, DNS records, and Docker container status. It is not a system health monitor. It tells you whether your services are reachable from the internet, not whether your server is healthy.

For a developer with one or two VPS instances, Uptime Kuma is often the right starting point. It requires minimal resources. On a 2GB RAM VPS, it runs comfortably alongside a web application without noticeable impact. ServerSpan's Uptime Kuma tutorial covers the full Docker installation, Nginx reverse proxy setup, and SSL configuration. The summary below assumes Docker is already installed.

mkdir uptime-kuma && cd uptime-kuma
cat > docker-compose.yml << 'EOF'
version: '3.3'
services:
  uptime-kuma:
    image: louislam/uptime-kuma:1
    container_name: uptime-kuma
    volumes:
      - ./uptime-kuma-data:/app/data
    ports:
      - "3001:3001"
    restart: always
EOF
sudo docker compose up -d

After deployment, access the dashboard at http://your-server-ip:3001, create an admin account, and add monitors. For a typical web application, configure three checks:

  • HTTP(s) monitor on your website URL with a 30-second interval and a 60-second timeout. This detects complete outages.
  • TCP monitor on your database port (for example, 3306 for MySQL) with a 60-second interval. This detects when the database process stops responding.
  • DNS monitor on your domain name with a 5-minute interval. This detects nameserver or DNS resolution failures.

Uptime Kuma supports over 90 notification channels. For VPS operators, Telegram is the most reliable free option. Create a Telegram bot via BotFather, obtain the bot token and your chat ID, and add the notification channel in Uptime Kuma settings. Test the alert before you need it.

The limitation of Uptime Kuma is that it only sees the outside of your server. It will tell you that your website is down. It will not tell you that the disk is 95% full and the database is about to crash because it cannot write temporary files. For that, you need internal monitoring.

Netdata: Real-Time Health Metrics Without the Bloat

Netdata is an open-source system monitoring agent that collects hundreds of metrics per second and displays them in a web dashboard. It tracks CPU, memory, disk I/O, network, temperature, systemd services, and application-specific metrics such as MySQL, Nginx, and Redis. It is designed to run on every server with minimal overhead.

The resource footprint is the key advantage. Netdata uses roughly 1% of a single CPU core and 50-100MB of RAM on a typical VPS. On a ServerSpan ct.Ready plan with 2 cores and 2GB RAM, this is negligible. It does not require a separate database server or complex configuration files.

wget -O /tmp/netdata-kickstart.sh https://get.netdata.cloud/kickstart.sh
sh /tmp/netdata-kickstart.sh --stable-channel

This one-line installer handles dependencies, creates the systemd service, and starts the agent. The dashboard is available at http://your-server-ip:19999. The default configuration collects metrics without requiring manual setup.

The most useful dashboards for a VPS running web services are:

  • CPU: Breakdown by user, system, and I/O wait time. I/O wait above 20% usually means disk saturation, not CPU overload.
  • RAM: Used, cached, buffered, and free memory. On Linux, high "used" memory is normal if "cached" is also high. Watch for low "free" memory and high "swapped" memory.
  • Disk I/O: Read and write throughput, operation latency, and utilization percentage. Disk latency above 50 milliseconds on an SSD indicates a problem.
  • Network: Incoming and outgoing throughput, packet drops, and TCP connection counts. Sudden drops in throughput often precede connectivity issues.
  • Systemd services: Status of individual services such as Nginx, MySQL, or PHP-FPM. A service showing as "failed" is an immediate alert trigger.

Netdata includes built-in health alarms for common conditions such as high CPU, low RAM, and disk fill. The default thresholds are conservative. Adjust them in /etc/netdata/health.d/ to match your workload. For example, a database server can safely run at 80% memory usage. A static website with no caching should alarm at 60%.

The free version of Netdata stores only a few hours of high-resolution data on the local server. For long-term trending, you need Netdata Cloud or a separate storage backend. For immediate troubleshooting and current-state monitoring, local storage is sufficient.

Zabbix vs. Prometheus: When You Outgrow the Basics

Uptime Kuma and Netdata cover the two monitoring layers for a single VPS. When you manage multiple servers, containers, or distributed services, you need a centralized monitoring platform. Zabbix and Prometheus are the two most common open-source choices. They differ in architecture, resource requirements, and learning curve.

Zabbix for multi-server fleets

Zabbix is a traditional monitoring platform with a centralized server and agents installed on each monitored host. The server stores data in a MySQL or PostgreSQL database and provides a web interface for dashboards and alerts. The agent on each server collects metrics and sends them to the server on a configured interval.

The architecture is straightforward for small to medium fleets. Install the Zabbix agent on each VPS, point it to the Zabbix server IP, and configure host templates in the web interface. Templates exist for Linux, Nginx, MySQL, PostgreSQL, and many other services. The agent footprint is small: approximately 10-20MB RAM and minimal CPU usage.

# Debian/Ubuntu agent installation example
wget https://repo.zabbix.com/zabbix/7.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_latest_7.0+ubuntu24.04_all.deb
dpkg -i zabbix-release_latest_7.0+ubuntu24.04_all.deb
apt update
apt install zabbix-agent2
systemctl enable zabbix-agent2 --now

The Zabbix server requires more resources. A minimal installation with a few dozen hosts needs 2-4GB RAM and a dedicated database. For a small fleet of five to ten VPS instances, this is manageable. For a single VPS, it is overkill. The practical threshold for choosing Zabbix is when you have more than five servers to monitor and need centralized alerting and long-term storage.

Prometheus and Grafana for container-heavy stacks

Prometheus is a time-series database designed for modern infrastructure. It pulls metrics from exporters running on target servers, stores them locally, and provides a query language (PromQL) for analysis. Grafana connects to Prometheus and renders dashboards. This stack is the standard for Kubernetes and Docker Swarm environments.

The architecture is pull-based. Prometheus periodically scrapes an HTTP endpoint on each target server. The Node Exporter provides Linux system metrics. The cAdvisor exporter provides container metrics. The Nginx exporter provides web server metrics. You configure the scrape targets in prometheus.yml.

scrape_configs:
  - job_name: 'node'
    static_configs:
      - targets: ['10.0.0.1:9100', '10.0.0.2:9100']

Prometheus is more flexible than Zabbix but has a steeper learning curve. PromQL queries require understanding of time-series concepts. Alertmanager configuration is file-based and less visual than Zabbix trigger configuration. Grafana dashboard creation requires more setup than Zabbix's built-in templates.

Choose Prometheus when you are running container orchestration, need custom metric collection, or want to integrate with application-level instrumentation (OpenTelemetry, custom application metrics). Choose Zabbix when you need a traditional host-monitoring platform with out-of-the-box templates and a lower barrier to entry.

Alerting That Actually Wakes You Up

A monitoring system without reliable alerting is a dashboard you ignore. The goal is to receive actionable notifications for real problems, without noise that trains you to ignore alerts.

Notification channels

For individual developers and small teams, three channels cover most needs:

  • Telegram: Free, reliable, and fast. Create a bot via BotFather, add the token to your monitoring tool, and send alerts to a private chat or group. Delivery is usually under two seconds.
  • Discord: Useful if your team already coordinates there. Create a webhook URL in your server settings and paste it into the monitoring tool. Formatting is richer than Telegram.
  • Email: The fallback that always works. Configure SMTP credentials in your monitoring tool. For self-hosted setups, be aware that many VPS providers block port 25 by default to prevent spam. ServerSpan SMTP restrictions can be lifted on request.

For production services, use at least two channels. If Telegram fails because of an API outage, email still delivers. If email is delayed by greylisting, Telegram is immediate.

Reducing noise: thresholds and alert fatigue

Alert fatigue is the most common monitoring failure. A threshold set too low generates alerts for normal behavior. A threshold set too high misses real problems. The correct threshold depends on your workload baseline.

Start with these guidelines and adjust after observing one week of production data:

  • CPU: Alert at 85% sustained for 5 minutes. A brief spike to 100% during a backup is normal.
  • Memory: Alert at 90% sustained for 10 minutes. On Linux, cached memory is not a problem. Alert on low free memory and high swap usage.
  • Disk: Alert at 85% full. At 90%, many applications fail to write logs or temporary files.
  • Disk latency: Alert at 50ms average over 5 minutes on SSD. On NVMe, alert at 20ms.
  • Service down: Alert immediately. A failed Nginx or MySQL process is never normal.

Use hysteresis to prevent flapping. If a CPU alert triggers at 85%, it should not clear until the CPU drops below 75%. This prevents a series of rapid on/off alerts when the CPU hovers near the threshold.

For Uptime Kuma, configure notification channels per monitor group. Group critical services (payment processing, authentication) together and use aggressive alerting. Group non-critical services (staging environments, internal tools) together and use business-hours-only alerting. This prevents a staging server restart from waking you at midnight.

When Monitoring Becomes Someone Else's Job

Self-hosted monitoring is the right choice for developers who want control and learning. It is not the right choice when monitoring is a distraction from your actual work. The time spent maintaining monitoring tools, tuning thresholds, and responding to alerts at night has a real cost.

The practical threshold for outsourcing is usually between five and ten servers. Below that, the overhead of a managed monitoring service may exceed the time you spend maintaining your own stack. Above that, the complexity of centralized alerting, log aggregation, and incident response becomes a specialized job.

If you are managing a growing fleet and would rather focus on your application than on monitoring infrastructure, ServerSpan's Linux server administration service covers 24/7 monitoring, alerting, and incident response. This includes server-level monitoring, service health checks, and proactive maintenance across the infrastructure.

For a single VPS or a small cluster, start with the tools in this guide. Deploy Uptime Kuma for external checks. Add Netdata for internal health metrics. Upgrade to Zabbix or Prometheus when you outgrow the basics. Use the ServerSpan sysctl generator to tune kernel parameters for better observability and resource handling. And choose a VPS plan with enough RAM and CPU to run your application and monitoring without starving either.

FAQ

How much RAM does monitoring use?

Uptime Kuma uses approximately 100-200MB. Netdata uses 50-100MB. Zabbix agent uses 10-20MB. Prometheus server needs 500MB to 2GB depending on retention. On a 1GB RAM VPS, running both Uptime Kuma and Netdata alongside a web application is tight. A 2GB plan is more comfortable. ServerSpan's ct.Ready plan with 2GB RAM is the practical minimum for running an application plus monitoring.

Can I run monitoring on the same server as my application?

Yes, for small setups. Uptime Kuma and Netdata are designed to coexist with applications. For larger deployments, separate the monitoring server from the application servers. If your application server fails, you still want the monitoring server to send alerts. A second small VPS dedicated to monitoring is often worth the cost.

Should I use a third-party SaaS monitor instead?

SaaS monitoring services (UptimeRobot, Pingdom, Datadog) are easier to set up and require no server maintenance. The tradeoffs are cost, data privacy, and customization limits. A self-hosted stack costs only the VPS resources. It keeps your metrics on your own infrastructure. And it allows unlimited customization of thresholds, dashboards, and alerts. For budget-conscious developers and privacy-sensitive workloads, self-hosted monitoring is usually the better choice.

How do I monitor Docker containers specifically?

Uptime Kuma has a Docker container monitor type that checks whether a container is running. Netdata detects Docker containers automatically and shows per-container CPU, memory, and network metrics. For deeper container monitoring, use Prometheus with cAdvisor, which exposes container-level resource usage, network statistics, and filesystem metrics.

What is the simplest monitoring stack for a beginner?

Start with Uptime Kuma for external checks and Netdata for internal metrics. Both install in minutes, require minimal configuration, and have web dashboards that are readable without training. Add alerting via Telegram. This stack covers 90% of monitoring needs for a single VPS. Upgrade to Zabbix or Prometheus only when you have multiple servers or need advanced features.

Source & Attribution

This article is based on original data belonging to serverspan.com blog. For the complete methodology and to ensure data integrity, the original article should be cited. The canonical source is available at: Server Monitoring on Your VPS: Self-Hosted Uptime and Health Monitoring for Developers.