← Knowledge hub
Tutorialby Uptime Room· September 24, 2026· 6 min read

Server Health Check: Commands, Alerts and Blind Spots

A server health check has two halves: commands on the box for saturation, and a probe from outside for reachability. Here is how to run both.

A server health check is a routine that answers two separate questions: is this machine struggling, and can anyone reach it. Resource commands answer the first and cannot answer the second. Most checklists only cover half the problem, which is why a box with idle CPUs and a broken route still looks perfect on a dashboard.

What should a server health check measure?

Start with the layers that actually cause incidents, in the order they usually bite. Saturation first, then failed units, then listeners, then the clock.

LayerCommandThe number to read
Loaduptime and nprocload average divided by core count
Memoryfree -hthe available column, not free
Diskdf -h and df -ispace and inodes, separately
Servicessystemctl --failedany unit in a failed state
Listenersss -ltnpthe ports you expect, bound

Inodes deserve the callout. A filesystem can report 60% space used and still refuse to create files, because a directory full of tiny cache entries exhausted the inode table. df -h looks fine and every write fails.

Five commands that answer most questions

Run these in order. Together they take about two seconds and cover the majority of "the server feels slow" tickets.

uptime                       # load average, compare against nproc
free -h                      # available memory, not free memory
df -h /; df -i /             # space and inodes on the root filesystem
systemctl --failed           # units that died since boot
ss -ltnp                     # what is listening, and which process owns it

Load average is the one people misread. A load of 4.0 on a four-core machine is fully busy and fine. The same 4.0 on one core means work is queueing, and the number includes processes blocked on disk, so heavy I/O inflates it without any CPU pressure at all.

Memory is the second trap. On Linux the kernel spends idle RAM on page cache, so the free column is supposed to look small on a healthy machine. The free man page describes available as an estimate of how much a new workload could claim without swapping, and that estimate is the one to threshold on.

systemctl --failed earns its place because it catches something no graph shows. A unit that exited an hour ago consumes no CPU, no memory and no disk, so every resource panel stays flat while the service is simply gone. Pair it with ss -ltnp, documented in the iproute2 manual, to confirm the ports you expect are actually bound.

Turning a command into something that pages you

Running commands by hand is inspection, not monitoring. The bridge most people build first is a cron job that reports in, and it works well for the box itself.

*/5 * * * * /usr/local/bin/checks.sh && curl -fsS -m 10 https://uptimeroom.com/api/heartbeat/<your-id> > /dev/null

The logic matters more than the syntax. The script exits non-zero when a threshold is crossed, the && withholds the ping, and the monitor fires an alert when the expected ping does not arrive. That inbound pattern is covered properly in our guide to heartbeat monitoring.

We prefer a five-minute interval with a grace period of twelve minutes here. Two consecutive misses then page someone, and a single slow cron run does not. The -f and -m flags matter too, because without them curl exits zero on a 500 and can hang for minutes.

Is a ping enough to call a server healthy?

No. ICMP proves a network stack replied, which is a smaller claim than it sounds. The kernel answers pings while the disk is full, every service has crashed and SSH refuses connections.

It is still worth running, because it separates two very different incidents. A host that stops answering ICMP is a routing, power or hypervisor problem. A host that answers ICMP while its port is closed is an application problem, and those go to different people at three in the morning. Our post on ICMP checks and what they prove goes through the cases.

Watching the machine from outside

Everything above runs on the box, and everything above dies with the box. Think of a kernel panic, a full disk that stops cron, or a default route deleted by a botched firewall rule. In each case the internal server health check stops reporting. Silence then looks identical to a working system, unless something is watching from elsewhere.

An external probe is the fix, and it needs to test the surfaces users touch. A tcp check on 22 or 3306, an http check on the application port, and a ping check on the host address together tell you which layer failed.

curl -X POST https://uptimeroom.com/api/v1/monitors \
  -H "Authorization: Bearer urm_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "web01 https",
    "type": "http",
    "target": "https://web01.example.com/",
    "intervalSec": 60
  }'

We tested the failure mode deliberately on a small VPS by filling the root filesystem. Cron stopped and the heartbeat stopped. The external http check went down inside one interval, while the last metrics scraped before the outage showed nothing unusual.

Run the outside check from several regions, since one bad network path is not the same as an outage. Six regions are available as of September 2026, and the addresses to allow through a firewall are listed at our probe IP reference. The full monitor schema sits in the API reference.

Windows and managed hosts

On Windows the same layers apply through different tools. Get-Counter, Get-Service and Get-EventLog -LogName System -EntryType Error cover saturation, services and recent faults, and Microsoft's performance counter documentation explains which counters are worth sampling.

On a managed VPS you do not control the hypervisor, the network or the provider's edge. Your commands describe a guest that may be running perfectly inside an unreachable host. The provider's status page is not a substitute, because it updates after humans notice.

Steal time is the one guest-visible clue. The st column in top or vmstat counts cycles the hypervisor gave to someone else, so a rising number means a noisy neighbour rather than your own workload. It will not tell you the host is failing, but it explains latency that no local metric accounts for.

Common mistakes

Watching free memory instead of available. Linux uses spare RAM for page cache, so free memory is supposed to be small. Alerting on it produces constant noise and teaches everyone to ignore the alert.

Checking space without checking inodes. They fail independently, and the inode version is far more confusing when you have not seen it before.

Treating the metrics agent as the monitor. Whatever scrapes CPU stops scraping when the machine goes down, and an absence of data is not an alert unless something is configured to notice. Read what a check result actually means before trusting a flat graph.

A complete server health check has two halves: commands on the box for saturation and failed units, and a probe from outside for reachability. Add a heartbeat so a machine that stops running jobs still raises something. The free plan covers 10 monitors at a one-minute interval as of September 2026, which is enough for a handful of hosts, so start free.

FAQ

How can I monitor my server health?

Combine three things. Run resource commands on the box for load, available memory, disk space and inodes, and failed units. Add a heartbeat from cron so a machine that stops running jobs raises an alert by going quiet. Then add an external check against the services users reach, because everything running on the box dies with the box.

How to do a Windows server health check?

The layers are the same and the tools differ. Get-Counter samples performance counters for processor, memory and disk queues, Get-Service reports stopped services that should be running, and Get-EventLog with the System log and an error filter surfaces recent faults. Schedule the script with Task Scheduler and have it report to an external monitor on success.

What is the best tool for monitoring servers?

It depends which half of the problem you have. Metrics agents are the right tool for saturation, trends and capacity planning, because they see inside the machine. External probes are the right tool for reachability, because they keep working when the machine does not. Most teams need both, and confusing them leaves a gap on whichever side is missing.

Why does a server look healthy while users cannot reach it?

Because the metrics come from inside. A deleted default route, a firewall rule, an expired certificate or a dead upstream all leave CPU, memory and disk looking completely normal. The agent keeps reporting healthy numbers right up to the moment it cannot reach the collector. Only a check that starts outside the network sees the failure.

Related reading