Your VPS suddenly feels sluggish, the load average is climbing, or your host emails you about resource overages. High CPU or memory usage is one of the most common — and most fixable — problems on a Linux VPS. The key is methodical diagnosis: find the process responsible before you change anything. This guide walks through the tools and the thought process to pinpoint and resolve runaway resource usage.
Start With the Load Average
Run uptime or top and read the three load-average numbers (1, 5, and 15-minute averages):
uptime
# load average: 3.40, 2.10, 1.05
Compare the load to your CPU count (nproc). A load of 4.0 on a 4-core VPS means it’s fully but healthily busy; 4.0 on a 1-core VPS means processes are queuing and everything feels slow. A rising trend (1-min far above 15-min) means the problem is happening right now.
Find the Culprit With top / htop
htop (install it if needed) is the friendliest live view. In plain top, press P to sort by CPU or M to sort by memory:
top -o %CPU # sort by CPU
top -o %MEM # sort by memory
# Top 5 CPU-hungry processes, scriptable
ps aux --sort=-%cpu | head -6
Note the PID, the command, and the %CPU/%MEM columns. Common offenders on a web VPS are PHP-FPM workers, MySQL/MariaDB, a backup or cron job, or a single abusive Apache process.
Diagnosing High CPU
If one process is pinning a core, dig into why:
- MySQL high CPU — run
SHOW FULL PROCESSLIST;to find slow or stuck queries; check the slow query log and add missing indexes. - PHP-FPM high CPU — a traffic spike, a bot attack, or an inefficient plugin. Check your access logs for a flood of requests to one URL.
- kswapd0 high CPU — this is the kernel swapping; it’s really a memory problem (see below).
- Unknown process — could be malware/crypto-mining. Investigate with
ls -l /proc/<PID>/exeandlsof -p <PID>.
Diagnosing High Memory
Check memory with free -h. The number that matters is available, not free — Linux deliberately uses spare RAM for cache and gives it back on demand:
free -h
# total used free shared buff/cache available
# Mem: 3.8Gi 2.9Gi 180Mi 60Mi 760Mi 620Mi
If available is very low and swap is filling, the system thrashes and slows to a crawl. Worse, the kernel OOM killer starts terminating processes — check for it:
dmesg | grep -i "killed process"
grep -i "out of memory" /var/log/syslog
Seeing the OOM killer means you’ve genuinely run out of RAM — you need to reduce usage or add memory, not just restart.
Fixing the Problem
| Cause | Fix |
|---|---|
| Too many PHP-FPM children for the RAM | Lower pm.max_children to fit available memory |
| MySQL buffer pool too large | Reduce innodb_buffer_pool_size |
| Slow queries spiking CPU | Add indexes; cache with Redis/object cache |
| Bot/DDoS traffic | Rate-limit or block at Cloudflare / firewall |
| No swap, frequent OOM | Add a small swap file as a safety net |
| Genuinely outgrown the plan | Upgrade RAM/CPU |
Adding a swap file gives the kernel breathing room and prevents hard OOM crashes:
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile && swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
Set Up Early Warning
Don’t wait for the next slowdown. Lightweight monitoring like netdata, Glances, or even a simple cron alert lets you catch a climbing trend before it takes the site down — and gives you the historical graph to spot exactly when usage spiked.
Conclusion
High CPU or memory usage is rarely mysterious once you look properly. Read the load average against your core count, identify the process with top/htop, confirm whether it’s CPU- or memory-bound, then apply the targeted fix — tune PHP-FPM and MySQL, block abusive traffic, add swap, or upgrade. Diagnose first, change one thing at a time, and your VPS will stay responsive.
