
If you can only glance at one number to answer "is something wrong right now," make it load average. Run uptime and you get three numbers — the average number of processes wanting CPU time over the last 1, 5, and 15 minutes. The 1-minute figure tells you what's happening this instant; the 5- and 15-minute figures tell you whether that spike is new or has been building. A rising trend across all three, rather than a single 1-minute blip, is the pattern worth acting on.
The number on its own is meaningless without context. Load average isn't a percentage — it's a count of work queued against your CPU cores. A load of 4.0 is idle on a 16-core box and badly overloaded on a single-core VPS. Always check nproc first and divide the load figure by that number; a result consistently above 1.0 per core means processes are queuing for CPU time rather than running immediately.
A single "CPU usage" percentage hides more than it reveals. A total CPU figure of 40% across an 8-core machine could mean every core is running at a comfortable 40%, or it could mean two cores are pinned at 100% while the rest sit idle — the second case is a real bottleneck for anything single-threaded, like a PHP-FPM worker or a MySQL query stuck on one core. Press 1 inside top to break the aggregate down per core and see which ones are actually maxed out.
It's also worth separating real CPU work from waiting. The %wa (iowait) field in top's header row shows time the CPU spent idle because it was waiting on a disk operation to finish. That time is counted as "busy" in some monitoring tools even though the processor isn't computing anything — a server can show high CPU usage while the real problem is a slow or overloaded disk, not an undersized CPU.
Run free -h and ignore the "free" column — look at "available" instead. Linux deliberately uses spare RAM for disk cache to speed up file access, which makes "free" look alarmingly low even on a healthy server. "Available" already accounts for cache that the kernel will happily release the moment an application actually needs the memory, so it's the number that tells you what headroom you really have.
The Swap line above isn't decoration — sustained swap usage, whether you check it there or with swapon --show, is a signal, not background noise. Swap exists as an emergency valve; a server that's routinely pushing megabytes into it is telling you it needs more RAM, or that a process is leaking memory over time and needs to be restarted (or fixed). Watching the swap figure stay flat at zero, day after day, is what a healthy server looks like.
Disk has two separate ceilings, and hitting either one takes a server down: raw space (df -h) and inode count (df -i). A partition can show 40% space used and still refuse to create a single new file if it has run out of inodes — usually caused by an application (a logger, a session store, a cache) writing enormous numbers of tiny files. Check both independently; they never move in lockstep.
On a database-heavy server, space is only half the story — throughput matters just as much. iostat -x 2 (from the sysstat package) shows %util and await per device; a disk pinned near 100% utilization with rising await times will make MySQL feel slow long before df -h shows any warning sign.
Two figures matter here: raw throughput and connection count. Bytes in and out per second — visible live with ifstat or read directly from /proc/net/dev — tell you whether you're approaching your provider's bandwidth cap or a NIC bottleneck. Connection count tells you a different story: how many clients are actually talking to the server right now.
ss -s is the modern replacement for netstat -s and gives an instant summary of total open TCP connections. A sudden spike here — say, from a baseline of a few hundred to tens of thousands — is worth investigating immediately. It could be a legitimate traffic surge from a marketing campaign going viral, or it could be a DoS-style abuse pattern hammering a single endpoint; either way, the connection count is usually the first metric to move before CPU or memory even notice.
Don't rely on a single manual check of connection count during an incident. By the time you notice a problem and run ss -s, a fast-moving spike may have already passed — or already taken the server down. Connection count needs to be graphed continuously, the same way CPU and memory are, so you can see the shape of the spike after the fact and tell a traffic surge from an attack.
Response time, error rate, and queue depth predict user-facing pain in a way that none of the system-level numbers above do on their own. Response time is the direct measure of what a visitor experiences. Error rate — specifically the count of 5xx responses in your nginx access or error logs — tells you how often that experience is actually broken rather than just slow. Queue depth, for anything running background jobs (mail sending, image processing, report generation), tells you whether work is piling up faster than it's being processed, which is often the earliest warning sign of all, showing up minutes before CPU or memory graphs move at all.
A server can look perfectly healthy on every system metric — load average under 1, plenty of available memory, disks nowhere near full — while a specific endpoint quietly times out for every third visitor because of an inefficient database query or a stuck external API call. That failure mode simply doesn't show up in CPU, memory, disk, or network graphs; it only shows up if you're measuring the application itself.
This is where CloudStick already does half the work for you without any setup. Every server connected to CloudStick has Zabbix Agent 2 (v7.0) installed automatically, reporting CPU, memory, and disk metrics straight back to the dashboard — powering the real-time Server Stats graphs on every plan, including Free. That covers all four of the system-level metrics discussed above with zero configuration, which means the effort you'd otherwise spend wiring up a monitoring agent is free to go toward the metrics that actually need custom instrumentation: tracking response times and 5xx counts in your application or reverse proxy logs, and queue depth if you're running background jobs. Start there — add response-time and error-rate logging to your highest-traffic endpoint this week, and you'll have the one category of metric CloudStick can't see for you covered too.

