Proxmox VEXVI · MonitoringMonitoring strategy
What to monitor across the Proxmox stack
What you'll learn
- Identify the metrics that matter at each layer and how much warning each one gives
- Distinguish metrics, logs, events, and alerts
- Explain why a running guest is not a healthy service, and where to measure instead
- Assign every signal to page, ticket or dashboard rather than alerting on all of them
Prerequisites
None — start here.
Verified against Proxmox VE 9.2.4 · Proxmox Backup Server 4.2.5 · Ceph Squid / Tentacle · Debian 13 (Trixie) · Linux kernel 7.0 (PVE 9.2 default) · 2026-08-12
Why this matters in production
You cannot operate what you cannot see. Monitoring that misses real incidents is as bad as no monitoring; monitoring that floods the team with noise is ignored.
The four observability axes
| Axis | What | When |
|---|---|---|
| Metrics | Numeric measurements over time | For trends and capacity |
| Logs | Discrete events with context | For forensics |
| Events | State changes | For alerting |
| Alerts | Derived from the above | For human attention |
A node being up is not a guest being healthy
Between “the hypervisor is powered on” and “the user can do their work” there are five distinct states. Four of them can be perfectly true while the service is completely unavailable, and every one of them is what somebody somewhere is using as their availability measurement.
| Level | What it proves | What can still be broken |
|---|---|---|
| 1. Node up | The hypervisor booted and is reachable | Every single thing above it |
2. Guest running | A QEMU or LXC process exists | Guest kernel panic, no network, filesystem read-only, application dead |
| 3. Guest agent responds | The guest kernel is alive and scheduling | The application, its dependencies, its data |
| 4. Port is open | Something is listening on the socket | The application returning errors to every request |
| 5. Endpoint returns the right answer, fast enough | What the user experiences | Only genuinely user-specific problems |
Each level is a necessary condition for the one below it and none is sufficient. A node with 400 days of uptime running a guest that has been serving HTTP 502 since lunchtime satisfies levels one through four.
set -euo pipefail
for vmid in $(qm list | awk '$3 == "running" {print $1}'); do
configured=$(qm config "$vmid" | awk -F'[ ,=]' '/^agent:/ {print $2}')
if [ "$configured" != "1" ]; then
printf '%-6s L2 only (no agent configured)\n' "$vmid"
elif qm guest cmd "$vmid" ping >/dev/null 2>&1; then
printf '%-6s L3 ok\n' "$vmid"
else
printf '%-6s L2 only (agent configured, NOT answering)\n' "$vmid"
fi
doneWhat to monitor
Hosts
| Metric | Why |
|---|---|
| CPU utilisation (host + per-VM) | Capacity planning |
Memory pressure (/proc/pressure/memory) | OOM risk |
| Disk I/O (await, utilisation) | Storage bottlenecks |
| Network errors and drops | Hardware failures |
| SMART / NVMe health | Disk failures |
| Temperature | Hardware failures |
| NTP offset | Cluster consistency |
Cluster
| Metric | Why |
|---|---|
| Quorum state | Cluster health |
| Corosync latency | Network health |
| pmxcfs sync status | Configuration consistency |
| HA state per resource | HA health |
Storage (ZFS)
| Metric | Why |
|---|---|
| Pool capacity | Running out |
| Pool fragmentation | Performance |
| Scrub status | Data integrity |
| Disk error counters | Hardware |
Storage (Ceph)
| Metric | Why |
|---|---|
| Cluster status (HEALTH_OK / WARN / CRIT) | Health |
| OSD latency p95, p99 | Performance |
| PG states (active+clean vs degraded) | Recovery |
| Pool utilisation | Capacity |
| nearfull warnings | Pre-emptive |
VMs and containers
| Metric | Why |
|---|---|
| CPU steal time | Host contention |
| Balloon / memory pressure | Memory overcommit |
| Disk I/O await | Storage issues |
| Guest agent status | Snapshot consistency |
Backups (PBS)
| Metric | Why |
|---|---|
| Last backup age per VM | RPO compliance |
| Last verify status | Data integrity |
| Datastore capacity | Storage |
| Sync job status | Off-site replication |
Security
| Metric | Why |
|---|---|
| Failed login attempts | Brute force |
| Configuration changes | Audit |
| New API tokens | Audit |
| Outbound connections to suspicious IPs | Exfiltration |
Alert design
flowchart LR
A[Metric source] --> B[Threshold check]
B --> C[Above threshold?]
C -->|yes| D[Alert]
C -->|no| E[No action]
D --> F[Notification]
Avoid alert storms by:
- Grouping related alerts.
- Using rate-of-change alerts instead of absolute thresholds.
- Suppressing alerts when a known incident is in progress.
Sort every signal into page, ticket or dashboard
Deciding what to monitor is the easy half. The half that determines whether the on-call rota is survivable is deciding what each signal is allowed to do.
| Destination | Criterion | Examples |
|---|---|---|
| Page | A human can act now, and waiting makes it materially worse | Tier-0 service unreachable; quorum lost; Ceph writes blocked; second OSD down in a failure domain; PBS datastore above 90% |
| Ticket with a deadline | Days of runway, but it will not fix itself | Single OSD down and recovering; OSD nearfull; deep scrubs behind; certificate expiring in 30 days; a guest whose agent stopped answering |
| Dashboard only | Useful for understanding, never for waking someone | CPU utilisation; network throughput; memory usage; guest counts |
The exercise worth doing once, deliberately, is taking every alert you currently have and assigning it to one of those three. Most estates discover that a substantial share of their pages belong in the second column and a few belong in the third, and moving them is the single largest improvement available to on-call quality.
Production considerations
Common mistakes
- Measuring at level 1 or 2 and calling it service availability.
- Alerting on every metric, which produces fatigue and then ignored pages.
- Alerting on utilisation rather than on pressure or saturation.
- Absolute thresholds where a rate of change would give weeks of warning.
- Running the monitoring inside the cluster it monitors.
- Watching causes and not symptoms, so a real outage with normal-looking causes is invisible.
- Never re-sorting existing alerts into page, ticket and dashboard.
Key takeaways
- There are five levels between a node being up and a service working; four of them can be true while the user sees nothing.
- Infrastructure monitoring fails optimistic, so at least one signal per service must come from a probe outside the cluster.
- Monitor the stack: hosts, cluster, storage, guests, backups, security.
- Assign every signal to page, ticket or dashboard, and re-do the exercise when the pager gets noisy.
- Prefer leading indicators and rate of change; utilisation is a poor predictor and pressure is a good one.
- If the cluster went dark, something outside it has to be what tells you.
Knowledge check
Knowledge check · 5 questions
Q1. A guest shows running in qm list, its guest agent answers, and its HTTP port accepts connections. What does this establish about service availability?
Q2. Which of these are good leading indicators - signals that give warning while remediation is still cheap? Select all that apply.
Q3. Running the monitoring stack as guests on the cluster it monitors produces an availability figure that is conservative, because gaps in the data are counted against you.
Q4. A team has forty alert rules and an on-call engineer who is paged three or four times a night. What is the most effective first step?
Q5. Why is rate of change generally more actionable than an absolute threshold for capacity signals?
Passing score: 75%. Answers are checked in this browser.