A good server alert threshold fires when a person needs to act, and stays quiet otherwise. In practice that means alerting on sustained values rather than single spikes, measuring load per CPU core rather than as a raw number, watching available memory and swap rather than “used RAM”, alerting on disk space early and on how fast it grows, and treating every unplanned reboot as worth knowing about. Split alerts into a warning level for working hours and a critical level that can wake someone, and review the numbers after every incident.
This guide goes through each metric, explains what a meaningful threshold looks like and ends with a table of starting values. They are starting points, not rules: every server has its own normal, and the right threshold is the one that matches it.
What a threshold is for
Every alert costs attention. An alert that fires and needs no action teaches people to ignore the next one, and the next one may be real. Before setting a threshold, answer three questions:
- What will break if this value keeps going, and how soon?
- What would the person receiving the alert actually do?
- Can it wait until morning?
If nothing breaks and nobody would act, it is a graph, not an alert. If it can wait until morning, it is a warning. Only what cannot wait should reach a phone at night.
Warning and critical levels
Two levels per metric work well for most teams:
- Warning: something is trending the wrong way. Send it to email or a team chat channel and handle it during working hours.
- Critical: an outage is close or under way. Send it to SMS or the on-call channel, day or night.
If your monitoring tool has one threshold per metric, you can get the same effect with routing: set the threshold where action is needed and choose the channel per server. A disk alert on a staging box can go to email; the same alert on the production database can go to the on-call team’s chat. Uptimecheck notifications are chosen per monitor, which makes that split simple.
Duration beats spikes
The most common source of noise is alerting on a single reading. CPU at 100 percent for ten seconds during a deployment, a backup or a cache rebuild is normal. CPU at 100 percent for twenty minutes is not. Wherever your tool allows it, add a duration: “above 90 percent for 10 minutes” instead of “above 90 percent”.
Where it does not, use metrics that already smooth over time. The 15-minute load average is a good example: a short burst barely moves it, while a sustained overload pushes it up and keeps it there.
CPU
High CPU on its own is rarely a problem. A busy server is a server earning its keep. CPU becomes a problem when it stays saturated long enough for requests to queue and response times to climb. Alert on sustained usage, and look at it together with response times from your uptime checks. If CPU is at 95 percent and response times are flat, the server is busy, not failing.
Load average per core
On Linux, the load average is roughly the number of processes running or waiting for CPU, and on Linux also those waiting for disk I/O, averaged over 1, 5 and 15 minutes. A raw load of 4 means nothing on its own: on a 16-core server it is light, on a 2-core server it is twice what the machine can handle. Divide by the number of cores before comparing, which nproc tells you.
- The 1-minute value reacts fast and is noisy. Use it for diagnosis, not alerts.
- The 15-minute value is the one to alert on. Above 1 per core means work is queuing; well above that, for a long time, means users feel it.
- High load with low CPU usually means processes waiting on disk or network storage. Look at I/O, not at code.
RAM and swap
“RAM used” is a misleading metric on Linux. The kernel uses free memory for the file cache and gives it back when applications need it, so a healthy server often shows memory nearly full. Look at available memory instead, the “available” column in free -m, which counts the cache that can be reclaimed.
Swap tells you more. A server that normally does not swap and starts doing so is under memory pressure, and performance drops sharply once active memory is paged to disk. Two useful signals:
- Swap use appearing or growing on a server that usually has none.
- Available memory falling steadily over days, which often points to a leak in a long-running process.
Database servers are a special case: they are configured to use most of the memory on purpose. Set their thresholds from what you see on a normal week.
Disk space and growth
A full disk is one of the most common causes of avoidable outages. Databases stop writing, logs stop rotating, sessions cannot be stored and backups fail. Disk is also the easiest metric to get right, because it rarely changes fast, which leaves time to act if you alert early.
- Use a percentage threshold for warning and critical, but adjust it for size. On a 2 TB volume, 10 percent free is still 200 GB; on a 20 GB volume it is 2 GB, which one bad log can eat in an afternoon.
- Watch growth as well as level. A disk at 70 percent that grew 10 points this week is more urgent than one that has sat at 85 percent for a year.
- Know what fills it: logs, backups kept locally, uploads, Docker images, database files. Each has a different fix.
Network
Network traffic is hard to set a fixed threshold for, because normal varies with the time of day and the season. Two patterns are worth an alert. Traffic far above the usual level, close to the capacity of the link, can mean a traffic spike, a scraper or an attack. Traffic that drops to nearly zero on a server that is normally busy can mean it has been taken out of the load balancer or lost its network, even if the machine itself looks fine. Learn the normal range from a few weeks of history before setting numbers.
Reboots
An unplanned reboot is always worth knowing about. It may be a kernel update, a hosting provider’s maintenance, a crash or an out-of-memory event. Even when everything comes back, services that are not set to start at boot, scheduled jobs that were due during the restart and mounted volumes can all be left in a bad state. Alert on every reboot outside a maintenance window, at warning level if the server recovered on its own.
Starting values
The values below are example starting points for a typical web or application server. Use them for the first few weeks, then adjust them to what you observe.
| Metric | Warning (example) | Critical (example) |
|---|---|---|
| CPU | Above 85% for 15 minutes | Above 95% for 15 minutes, with rising response times |
| Load average (15 min) | Above 1 per core | Above 2 per core |
| Available memory | Below 15% | Below 5% |
| Swap | Any use on a server that normally has none | Above 50% of swap in use |
| Disk | Above 80%, or full within a week at the current rate | Above 90%, or full within a day |
| Network | Well outside the normal range for the time of day | Near link capacity, or near zero on a busy server |
| Reboot | Any reboot outside a maintenance window | Services did not come back after a reboot |
Uptimecheck server monitoring measures CPU, load averages over 1, 5 and 15 minutes, RAM, swap, disk, network and reboots on Linux, Windows and macOS, with thresholds you set per server and resource. For background on why these numbers matter, see keeping your website running with server status monitoring.
Watch the symptoms too
Server metrics describe causes. Your users experience symptoms: slow pages, errors and failed jobs. Monitor both. An uptime check with response validation tells you when the site fails, and a heartbeat tells you when the backup did not finish. When a symptom alert and a resource alert fire together, the cause is usually obvious. When only the resource alert fires, you often have time to fix it before anyone notices.
This also lets you raise server thresholds with confidence. If the site is checked every minute, a CPU alert does not have to be the thing that catches an outage. It can be tuned for early warning instead of last resort. The same thinking applies to website checks; see how to reduce false alerts in uptime monitoring.
Review thresholds after incidents
Thresholds are never finished. After each incident, and once a month for noisy servers, ask:
- Did an alert fire before users noticed? If not, which metric moved first, and could a lower threshold have caught it?
- Which alerts fired that nobody acted on? Raise them, add a duration or move them to a daytime channel.
- Did the alert reach someone who could act? If not, change the routing.
- Has the server’s normal changed after an upgrade, a migration or more traffic?
Write the answers into the incident report, so the change has a reason attached. The incident postmortem template has a section for exactly this.
Summary
Alert on what needs a human, at the level of urgency it really has. Use sustained values, load per core, available memory and swap, disk level and growth, and every unplanned reboot. Start with example values, learn each server’s normal and tune after every incident.
Uptimecheck puts server monitoring next to uptime checks, heartbeats and status pages in one account. Start a 14-day free trial, no credit card required.