Overview
Server monitoring means tracking the health and performance of your dedicated server over time — CPU load, memory usage, disk I/O, and network throughput. Without it, you’re flying blind. A spike in CPU usage or a disk filling up silently can take down your site or application before you even know there’s a problem.
Most performance issues don’t announce themselves. They build up gradually: a runaway PHP process, a MySQL query that starts taking 10x longer after a data import, a log file that quietly eats 40GB of disk space overnight. Good monitoring catches these before users do.
This article covers both real-time diagnostic tools (useful when something is already wrong) and persistent monitoring setups (useful for catching problems before they escalate). It applies to any Linux-based Dedicated Server running CentOS 7/8, AlmaLinux 8/9, Ubuntu 20.04/22.04, or Debian 11/12.
Prerequisites
- Root or sudo SSH access to your dedicated server
- A terminal client (e.g. PuTTY on Windows, Terminal on macOS/Linux)
- Basic familiarity with the Linux command line — you don’t need to be an expert, but you should know how to run a command
- If using WHM/cPanel: access to WHM as root
- Optional: an SMTP relay or email account configured for alert notifications
Step 1: Check Real-Time CPU and Memory Usage with top or htop
The fastest way to see what’s happening on a server right now is top. It’s installed on every Linux system by default. SSH into your server and run:
top
You’ll see a live-updating table of processes sorted by CPU usage. The header shows overall CPU, memory, and load averages. Press M to sort by memory instead, or q to quit.
htop is much easier to read and I’d recommend it for anyone who isn’t staring at top daily. Install it if it’s not already present:
# AlmaLinux / CentOS / RHEL
yum install htop -y
# Ubuntu / Debian
apt install htop -y
Then just run htop. You’ll get colour-coded CPU bars per core, memory usage, and a scrollable process list. Use F6 to change sort order.
📝 Note: Load average (shown in both tools) is often misread. A load of 4.00 on a 4-core server means the cores are fully saturated. On a 16-core server, the same number is nothing to worry about. Always read load average relative to your core count.
Step 2: Identify Disk Usage and I/O Bottlenecks
Disk problems are one of the most common causes of slow servers, and they’re often overlooked because CPU and RAM look fine. Check disk space first:
df -h
This shows all mounted filesystems and their usage percentages. If / or /var is at 90%+, that’s urgent. /var fills up most often because it holds logs, mail queues, and databases.
To find what’s eating space in a specific directory:
du -sh /var/* | sort -rh | head -20
For live disk I/O — meaning which processes are reading/writing right now — use iotop:
# AlmaLinux / CentOS
yum install iotop -y
# Ubuntu / Debian
apt install iotop -y
# Run it
iotop -o
The -o flag shows only processes actively doing I/O, which makes it much less noisy.
⚠ Warning: If df -h shows a partition at 100%, some services will stop writing logs or accepting connections immediately. Don’t just delete random files — find the cause first with du before clearing anything.
Step 3: Monitor Network Traffic
High network usage can saturate your server’s bandwidth allocation or indicate something unexpected — like a DDoS, a misconfigured backup job, or a process exfiltrating data. Use nethogs to see bandwidth usage broken down by process:
# AlmaLinux / CentOS
yum install nethogs -y
# Ubuntu / Debian
apt install nethogs -y
# Run it on your primary interface (adjust eth0 to match yours)
nethogs eth0
To find your interface name, run ip a first. On newer systems it’s often ens3 or enp1s0 rather than eth0.
For a historical view of bandwidth, vnstat is excellent. It logs traffic passively in the background:
apt install vnstat -y # or yum
vnstat -d # daily summary
vnstat -m # monthly summary
Step 4: Review System Logs for Errors
Real-time metrics tell you the what; logs tell you the why. The main system log locations you should know:
/var/log/syslog(Debian/Ubuntu) or/var/log/messages(RHEL/AlmaLinux) — general system events/var/log/auth.logor/var/log/secure— SSH logins and authentication attempts/var/log/apache2/error.logor/var/log/httpd/error_log— web server errors/var/log/mysql/error.log— database errors and slow query info
To watch a log file live as entries come in:
tail -f /var/log/syslog
On systemd-based systems, journalctl is often more useful:
# Show errors from the last hour
journalctl --since "1 hour ago" -p err
# Follow logs for a specific service
journalctl -u nginx -f
Step 5: Set Up Persistent Monitoring with Netdata or Prometheus
Command-line tools are great for active diagnosis, but you can’t stare at htop all day. For ongoing monitoring with historical graphs and alerting, you need something persistent.
Netdata is my go-to for dedicated servers. It installs in under a minute, runs a local web dashboard on port 19999, and has zero configuration required to get basic metrics. Install it with:
wget -O /tmp/netdata-kickstart.sh https://my-netdata.io/kickstart.sh
bash /tmp/netdata-kickstart.sh --non-interactive
Once running, access it at http://your-server-ip:19999. You’ll get CPU per core, RAM, disk I/O, network, and more — all with 1-second resolution and 1 hour of history by default.
📝 Note: Netdata’s port 19999 is open to the world by default. Either restrict it in your firewall to your IP only, or put it behind a reverse proxy with authentication. Don’t leave it publicly accessible on a production server.
For larger infrastructure with longer retention and multi-server aggregation, Prometheus + Grafana is the standard stack. It’s more complex to set up but significantly more powerful. That’s worth a separate article on its own.
WHM users: If you’re running cPanel/WHM on your dedicated server, navigate to WHM > Server Status > Service Status and WHM > Server Information for a quick overview of service health and resource usage without leaving the interface.
Step 6: Configure Email or Slack Alerts
Monitoring without alerting is just a dashboard nobody watches. At minimum, set a disk space alert. With Netdata, alerts are configured in /etc/netdata/health.d/. The disk alert is already active by default — it fires at 85% and 95% usage.
To configure email notifications, edit:
nano /etc/netdata/health_alarm_notify.conf
Set SEND_EMAIL="YES" and add your address to DEFAULT_RECIPIENT_EMAIL. Netdata also supports Slack, PagerDuty, and webhook integrations in the same file.
Common Issues and Troubleshooting
High CPU but no obvious process in top
This usually means the offending process is forking and dying quickly, so it doesn’t show up in a snapshot. Run top with a faster refresh using top -d 0.5, or use atop which logs historical process data. Another common cause is kernel-level work showing as kworker or kswapd — kswapd being busy almost always means you’re low on RAM and the system is swapping heavily to disk.
Disk I/O is high but iotop shows nothing obvious
If MySQL or PostgreSQL shows up with moderate I/O but not extreme usage, the real issue might be a missing index causing full table scans on every query. Enable the slow query log in MySQL by setting slow_query_log = 1 and long_query_time = 1 in /etc/my.cnf, then restart MySQL. Review the log at /var/log/mysql/slow.log.
Memory usage climbs continuously until the server slows to a crawl
This is a memory leak, and it’s most often Apache with MaxRequestWorkers set too high, or PHP-FPM pool settings that allow too many child processes. Each Apache worker or PHP-FPM child can use 30-80MB. Multiply that by 200 workers and you’re in trouble fast. Check your current Apache config at /etc/httpd/conf/httpd.conf or /etc/apache2/apache2.conf and reduce MaxRequestWorkers to something your RAM can actually support.
df -h shows free space but disk writes are still failing
You’ve likely run out of inodes, not disk space. Inodes are metadata slots for individual files — you can exhaust them if you have millions of tiny files (common with session caches, Maildir mail stores, or certain CMS cache directories). Check with df -i. If any filesystem shows 100% inode usage, you need to find and clean up the file count, not just the file size.
Netdata dashboard is unreachable after install
Almost always a firewall issue. On AlmaLinux/CentOS with firewalld running, port 19999 is blocked by default. Open it temporarily with firewall-cmd --add-port=19999/tcp --permanent && firewall-cmd --reload. On Ubuntu with UFW: ufw allow 19999/tcp. Then restrict it to your IP as soon as you confirm it’s working.
FAQ
Frequently Asked Questions
How do I check CPU usage on a Linux dedicated server?
SSH into your server and run top or htop for a real-time process list sorted by CPU usage. For a quick one-line snapshot, mpstat 1 3 (from the sysstat package) gives you CPU usage averaged over 3 seconds per core. Always compare load average to your total core count — a load of 8.0 on a 16-core server is fine; on a 2-core server it means serious congestion.
What's the best free monitoring tool for a dedicated server?
Netdata is the easiest to get running quickly — one install command, no config needed, and you get a full real-time dashboard. For longer-term data retention and multi-server setups, Prometheus with Grafana is the industry standard, though it takes more time to configure. Both are free and open source.
How much RAM should a dedicated server have for web hosting?
It depends heavily on your software stack. A cPanel/WHM server running Apache, MySQL, and PHP for moderate traffic typically needs at least 4GB, with 8-16GB recommended for comfort. The bigger factor is your Apache and PHP-FPM worker count — each worker consumes RAM, and if your config allows more workers than your RAM supports, the server will start swapping to disk, which tanks performance.
How do I get alerted when my server disk is almost full?
Netdata includes a disk space alert out of the box — it fires at 85% and 95% usage. Configure email or Slack notifications in /etc/netdata/health_alarm_notify.conf. Alternatively, a simple cron job running df -h and mailing you the output works fine for basic setups. Either way, don’t rely on manual checks — disk-full events can happen faster than you expect.
My server feels slow but CPU and RAM look normal. What else should I check?
Disk I/O is the most common culprit people miss. Run iotop -o to see if any process is hammering the disk, and check df -i for inode exhaustion (not just disk space). Network latency is another factor — use mtr your-domain.com to check for packet loss between your server and the outside world. Slow DNS resolution can also make requests appear sluggish even when the server itself is healthy.