You cannot manage what you cannot measure. Without real-time visibility into CPU usage, memory consumption, disk I/O, and network throughput for your game servers, small problems become catastrophic failures waiting to happen. This guide explains how to deploy Prometheus and Grafana on your self-hosted VPS, configure container metrics collection, and build live dashboards that detect performance issues before players notice them.
The solution combines Prometheus (a metrics time-series database), Grafana (visualization layer), and node_exporter + cAdvisor (metrics collectors). We also show how M.A.F Cloud simplifies this stack by including built-in crash auto-restart and circuit breaker functionality without manual configuration or external dashboard setup.
Why Traditional Logging Falls Short for Performance Monitoring
Application logs tell you what happened after an incident: a player report of lag spikes, an OOM crash message, or a disk full error. Logs are reactive because they only capture events that occurred in the past minute.
Metrics answer different questions. A 30-second spike in CPU usage shows JVM garbage collection stress before Minecraft players see TPS drops. Memory growth over six hours indicates a plugin memory leak long before the server crashes. Network connection rate changes reveal bot attacks or DDoS patterns in near-real-time.
For production environments, you need three layers:
**Logs:** What errors and warnings occurred
**Metrics:** How resources behaved over time (CPU%, RAM %, requests/second)
**Alerts:** Automated triggers when thresholds are breached (e.g., RAM > 85% for 5 minutes)
This guide covers the metrics and alerting layer with Prometheus and Grafana.
Core Components Explained
**Prometheus** collects and stores time-series data from exporters running on your host machine and inside containers. It queries metrics using PromQL (Prometheus Query Language) for visualization or alerting rules.
**node_exporter** runs as a Docker container or systemd service and exposes system-level metrics: CPU utilization across cores, memory free/used/ratio, disk space per partition, network bandwidth per interface, temperature sensors for fan speed control.
**cAdvisor (Container Advisor)** is included natively in recent Docker versions but works best when running as a separate container. It monitors per-container CPU, memory, network I/O, and block device reads/writes.
**Grafana** connects to Prometheus as a data source and renders visualizations: line charts for trends, gauge meters for real-time snapshots, heatmaps for distribution patterns, and tables for listing services. Dashboards can include multiple Prometheus queries on one screen.
**Alertmanager** integrates with Prometheus to send notifications via email, Slack, Discord webhooks, or PagerDuty when specific conditions trigger. For example: if average RAM usage exceeds 90% for five consecutive minutes, restart the server automatically.
Step-by-Step: Deploy Prometheus and Grafana with Docker Compose
Create a docker-compose.yml file at /root/monitoring/docker-compose.yml:
yaml
version: '3.8'
services:
prometheus:
image: prom/prometheus:v2.47.0
container_name: prometheus
restart: unless-stopped
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
ports:
- '9090:9090'
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus_data:/prometheus
networks:
- monitor-net
grafana:
image: grafana/grafana:10.2.0
container_name: grafana
restart: unless-stopped
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin123
ports:
- '3000:3000'
volumes:
- grafana_data:/var/lib/grafana
networks:
- monitor-net
node_exporter:
image: prom/node-exporter:v1.6.1
container_name: node_exporter
restart: unless-stopped
command:
- '--path.rootfs=/host'
pid: host
volumes:
- '/:/host:ro,rslave'
networks:
- monitor-net
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.47.2
container_name: cadvisor
restart: unless-stopped
privileged: true
pid: host
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
networks:
- monitor-net
volumes:
prometheus_data:
grafana_data:
networks:
monitor-net:
```### Prometheus Configuration File
Create prometheus.yml in the same directory:
yaml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node_exporter'
static_configs:
- targets: ['node_exporter:9100']
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']
- job_name: 'container_metrics'
static_configs:
- targets:
- 'cadvisor:8080'
```Start the stack:
cd /root/monitoring && docker compose up -d
Access Grafana at http://your_vps_ip:3000 with default credentials admin/admin123. Change the password immediately after first login.
Import Pre-Built Dashboards
Instead of building charts manually, import community-maintained dashboards designed for Docker and system monitoring.
### System Metrics Dashboard (ID: 1860)
In Grafana, go to Dashboards → Import and enter dashboard ID 1860. This displays CPU percent usage per core, memory free/used/dirty buffers/cache, disk space per mount point, network throughput per interface, and temperature readings.
### Container Metrics Dashboard (ID: 14871)
Import ID 14871 to view per-container resource consumption: which containers consume the most RAM, CPU spikes during startup, network I/O per second, and block device read/write latency. This is critical for detecting slow plugins or inefficient builds in Node.js or Python apps.
### Docker Networking Dashboard (ID: 10971)
Import ID 10971 to track container network activity: total packets sent/received per container, TCP retransmit counts, UDP packet loss, and active connections. Essential for diagnosing why Minecraft players experience lag spikes even when your VPS CPU is underutilized.
Setting Up Alerting Rules
Prometheus evaluates alert rules every 15 seconds (or however frequently you set global.evaluation_interval). When a condition matches, it sends the notification to Alertmanager.
Create alerts.yml file:
yaml
groups:
- name: game_server_alerts
interval: 1m
rules:
- alert: HighMemoryUsage
expr: container_memory_usage_bytes{container_name="mc-paper-server"} / container_spec_memory_limit_bytes{container_name="mc-paper-server"} > 0.85
for: 5m
labels:
severity: warning
annotations:
summary: "High memory usage detected on mc-paper-server"
description: "Container memory usage {{ $value | humanizePercentage }} exceeds 85% threshold for 5 minutes"
- alert: ContainerRestartLoop
expr: rate(container_last_seen{container_name="mc-paper-server"}[5m]) == 0
for: 2m
labels:
severity: critical
annotations:
summary: "mc-paper-server container has restarted repeatedly"
```Add alerts.yml to your Prometheus config:
yaml
rule_files:
- '/etc/prometheus/alerts.yml'
```Configure Alertmanager integration in Grafana. Go to Alerting → Contact points and add a Discord webhook URL where your team receives instant notifications whenever memory usage spikes or containers restart unexpectedly.
M.A.F Cloud Built-In Crash Protection vs DIY Prometheus Setup
DIY observability stacks give fine-grained visibility into every aspect of your infrastructure, but require ongoing maintenance: updating Prometheus and Grafana images quarterly, tuning scrape intervals to avoid excessive resource consumption, debugging alert rule syntax, replacing failed collectors, managing dashboard imports.
If you prefer zero-setup monitoring, M.A.F Cloud includes crash protection and automatic recovery directly in the panel.
When you deploy any game server through M.A.F Cloud (including Paper Minecraft, Palworld, Rust, or Python applications), the following features activate automatically:
**Crash detection**: The agent monitors process health continuously. If Java exits abnormally due to OOM or plugin error, the server restarts within seconds rather than waiting for you to discover the issue via SSH or Telegram alerts
**Circuit breaker for AI self-heal**: If a corrupted chunk causes repeated crashes, M.A.F Cloud's AI-assisted self-healing system analyzes patterns and either rolls back world state or resets problematic configurations automatically. This only activates on servers enrolled with free-tier models to avoid unnecessary API calls.
**Live WebSocket console**: See startup logs and crash traces in real-time from the browser without configuring log aggregation tools like Loki or ELK stacks.
**Allocation port probes**: Before players try connecting, each game server allocation runs connectivity tests to verify the assigned port accepts traffic over TCP and UDP protocols.
Free tier includes all of this for 1 server with 2 GB RAM. Pro tier (RM 29.90/month) and Studio tier (RM 59.90/month) expand capacity for unlimited servers while keeping monitoring fully automated.
Building Custom Dashboards for Game Server Health
Once basic metrics work, extend dashboards with game-specific indicators. For Minecraft servers specifically, you may want to display:
**TPS (Ticks Per Second):** Ideally 20.0 constantly. Drops below 18 indicate severe performance degradation affecting all gameplay mechanics.
**Player count trend:** Over time, sudden population shifts often precede griefing incidents or bot spam campaigns.
**Chunk pre-generation progress:** During world initialization, monitor how fast new terrain generates. Slow chunk loading correlates directly with high memory pressure.
These custom metrics require additional exporters or application-side instrumentation. However, standard container metrics (CPU, RAM, network) already provide early-warning signs: rising memory usage suggests chunk cache bloat; sustained 100% CPU on single core indicates inefficient mod behavior; network retransmits suggest router congestion on your VPS provider.
Conclusion: Monitor Everything or Accept Outages
Without Prometheus and Grafana, you rely entirely on player reports to identify problems. By the time someone tells you their Minecraft world freezes periodically, you have already missed dozens of similar incidents occurring throughout the week. Investing ten minutes setting up metrics gives you visibility into what matters before users complain.
However, remember that advanced monitoring is optional if you prioritize ease-of-use over granular control. M.A.F Cloud provides built-in crash protection, automated recovery, and real-time console output so you can focus on deploying servers instead of managing dashboards. Choose whichever approach matches your skill level and operational needs.