SYSTEMS OPERATIONAL
VPS

VPS Running Slow? How to Find and Fix High CPU Usage

Getwebup 5 min read

Your site is crawling, SSH takes forever to respond, and your monitoring dashboard has a red CPU graph pinned near 100%. Before you reach for a bigger VPS plan, spend ten minutes finding out what's actually burning the CPU - most of the time it's one runaway process, not a genuine capacity problem.

Symptom: What High CPU Actually Looks Like

It's not always obvious. Sometimes it's a slow website with normal-looking traffic. Sometimes it's SSH sessions that lag on every keystroke. Sometimes cPanel or WHM itself becomes sluggish because the load average has climbed past your core count. If uptime shows a load average of 8.00 on a 2-core VPS, that's your first confirmation - anything sustained above your core count means processes are queued and waiting for CPU time.

uptime
# 14:32:10 up 41 days,  3:12,  2 users,  load average: 8.42, 7.90, 6.11

Step 1: Find the Process That's Actually Guilty

Don't guess - measure. SSH in and run:

top -o %CPU

or, if it's installed, htop for a friendlier view. Watch it for 30-60 seconds rather than reacting to the first snapshot - a process spiking briefly during a cron job is different from one pegged at 100% continuously. Note the process name, PID, and which user owns it (that tells you which cPanel account or app is responsible on a shared VPS).

Four culprits show up again and again:

1. PHP-FPM or Apache/LiteSpeed workers

If you see a wall of php-fpm or httpd processes each using real CPU, it's almost always WordPress or another CMS doing expensive work per request - usually uncached pages, a plugin running a heavy query on every load, or a REST API endpoint (wp-json) being hammered by bots. Check your web server's access log for the busiest IPs and URLs in the last few minutes:

tail -n 5000 /usr/local/apache/domlogs/yourdomain.com |
  awk '{print $1}' | sort | uniq -c | sort -rn | head -10

A single IP making thousands of requests in a short window is a scraper or a broken script, not a real visitor.

2. MySQL / MariaDB

If mysqld is the top consumer, you likely have a slow, unindexed query running repeatedly. Turn on the slow query log temporarily:

mysql -e "SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 2;"
tail -f /var/lib/mysql/$(hostname)-slow.log

Anything that shows up repeatedly is your target - it's usually a missing index on a large table, or a plugin (analytics, SEO, backups) that scans the whole database on every page load.

3. Cron jobs that overlap

A backup, malware scan, or WP-Cron task that takes longer than its own interval will start stacking copies of itself. Check what's scheduled:

crontab -l
cat /etc/cron.d/* 2>/dev/null

If you see the same script listed as running via both system cron and WordPress's own wp-cron.php, or a backup job scheduled every 15 minutes that actually takes 40 minutes to finish, that's your overlap.

4. Bad bots and vulnerability scanners

Automated scanners hitting wp-login.php, xmlrpc.php, or random plugin paths thousands of times an hour will chew through CPU on the auth and PHP layers even when every request fails. This is common enough that it deserves its own check - if your access log is dominated by requests to login or admin-ajax endpoints from IPs with no referrer, that's what you're looking at.

Fix: Match the Response to the Cause

CauseFix
Uncached PHP requestsEnable a page cache (WP Super Cache, LiteSpeed Cache, or server-level cache) and OPcache
Slow database queryAdd the missing index, or disable/replace the plugin causing it
Overlapping cron jobsStagger schedules, add a lock file so a job can't start while a previous run is still active
Bots hammering login/API endpointsRate-limit or block via fail2ban, restrict xmlrpc.php, add a firewall rule (ModSecurity, CSF, or UFW)
One account overusing shared resourcesSet a CloudLinux CageFS / CPU limit on that account, or move it to its own VPS

For an immediate, temporary fix while you diagnose properly, you can kill or renice a specific runaway process without rebooting the whole server:

# Lower priority instead of killing, if it's still needed
renice +10 -p <PID>

# Kill it outright if it's clearly stuck
kill -9 <PID>

That buys you breathing room - it doesn't fix the underlying cause, so don't stop there.

Blocking a Bad IP Fast

If a scanner or scraper is the problem, block it at the firewall rather than the application layer - it's cheaper on CPU because the request never reaches PHP:

# CSF (common on cPanel servers)
csf -d 203.0.113.45

# Plain iptables
iptables -A INPUT -s 203.0.113.45 -j DROP

Prevention

  • Set up monitoring with alerts. A load-average alert that fires at 70% of your core count gives you time to act before visitors notice anything.
  • Cache everything cacheable. Page caching turns most CPU-bound requests into near-free static file serves.
  • Audit plugins and cron jobs quarterly. Old, abandoned plugins are consistently the biggest source of unexplained CPU spikes on WordPress VPS setups.
  • Rate-limit login and API endpoints. Fail2Ban with a WordPress-specific jail, or a simple limit_req zone in Nginx, stops most credential-stuffing bots before they cost you CPU.
  • Right-size the plan. If your load average is consistently high with no single guilty process, you've outgrown the plan - that's a real scaling problem, not a bug to chase.

Most "my VPS is slow" tickets we see resolve in one of these five buckets. Spend the first ten minutes with top and your access logs before assuming you need more hardware - it's usually cheaper and faster to fix the actual cause.

Frequently asked questions

How do I check CPU usage on my VPS without installing anything?

Run `top` or `uptime` over SSH - both are pre-installed on every Linux distribution. `top -o %CPU` sorts processes by CPU usage so the worst offender is at the top of the list.

Is a load average of 4 bad on my VPS?

It depends on your core count. A load average roughly equal to or below your number of CPU cores is fine. If it's consistently higher than your core count, processes are queuing for CPU time and requests will feel slow.

Will restarting the server fix high CPU usage?

It can give you temporary relief by killing the runaway process, but the underlying cause - a bad plugin, missing index, or bot attack - will come back unless you fix it directly.

How do I stop bots from overloading my VPS?

Block offending IPs at the firewall (CSF or iptables), restrict access to `xmlrpc.php` and `wp-login.php`, and add rate limiting with Fail2Ban or your web server's built-in request-limiting module.

Should I upgrade my VPS plan instead of debugging this?

Only after you've confirmed there's no single runaway process - if `top` consistently shows load spread evenly across many legitimate requests with no bad actor, that's a genuine capacity issue and upgrading makes sense.

#vps #high-cpu #server-performance #linux #troubleshooting #php-fpm

Keep reading

Chat with Support