High CPU usage on a VPS almost always has a specific culprit: a runaway process, an aggressive bot hammering your site, or a poorly optimized script. Pinpointing that process in under two minutes is usually enough to fix the problem without blindly rebooting anything.
Why Does VPS CPU Hit 100%?
A VPS shares the physical host hardware through virtualization but gets a fixed CPU core quota. When that quota is exhausted, requests pile up and your site slows to a crawl or stops responding entirely.
The most common causes include:
- Malicious traffic or scraping bots generating thousands of requests per minute.
- MySQL/MariaDB queries without indexes triggering repeated full-table scans.
- PHP plugins or scripts with infinite loops or memory leaks.
- Indexing processes (search engines, Elasticsearch) running without resource limits.
- Overlapping cron jobs because the previous run hasn't finished before the next one fires.
- Malware or cryptomining software injected into the server.
How to Identify the Offending Process
Before changing anything, diagnose first. Connect via SSH and run these commands in order:
1. View real-time load
top -o %CPU
The %CPU column sorted descending shows the hungriest process at the top. Note the PID and command name.
2. Dig deeper with htop
htop
If installed, htop shows per-core usage, load averages, and lets you kill processes without leaving the view. A sustained load average above the number of available cores confirms saturation.
3. Pinpoint Apache/Nginx processes
ps aux --sort=-%cpu | head -20
Useful when dozens of web server processes are running. This tells you whether the issue comes from PHP-FPM, Apache workers, or something unrelated like a Python script or third-party daemon.
4. Check access logs for bots
tail -n 500 /var/log/apache2/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20
If you see a single IP with hundreds of requests in seconds, that IP is generating the load spike.
Step-by-Step Fixes
Kill the process immediately
If the culprit is a runaway process that shouldn't be running:
kill -15 <PID>
Use kill -9 <PID> only if the process ignores signal 15. Restart the affected service after investigating the root cause.
Block aggressive IPs or bots
Once you've identified the offending IP, block it with iptables:
iptables -A INPUT -s 1.2.3.4 -j DROP
For longer-lasting protection, configure fail2ban or enable your control panel's WAF. If Cloudflare is in front of your site, a JS challenge or IP block in the dashboard is cleaner than an iptables rule.
Optimize database queries
Enable the slow query log in MariaDB/MySQL:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
Review the resulting log and add indexes to columns that appear in EXPLAIN output without using an index (type: ALL).
Limit PHP-FPM or Apache workers
If the web server itself is spawning too many processes, adjust php-fpm.conf:
pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 10
The right value for pm.max_children depends on available RAM and average memory per process. A practical rule: RAM available for PHP ÷ average memory per process.
Fix overlapping cron jobs
crontab -l
cat /etc/cron.d/*
If a heavy task runs every minute but takes longer than 60 seconds, runs stack up. Add a lock file or use flock:
* * * * * flock -n /tmp/task.lock /path/to/task.sh
When Optimization Isn't Enough
If CPU stays pegged after all optimizations, the current resource plan simply can't handle real traffic anymore. At that point you have two paths: scale vertically (more cores on the same VPS) or distribute load across multiple servers.
To decide whether to upgrade your current plan or move to a different setup, visit our complete VPS server guide comparing plans by workload type.
| Symptom | Likely cause | Quick fix |
|---|---|---|
| Sudden CPU spike to 100% | Bot / Layer-7 DDoS | Block IP, enable WAF |
| High CPU only during traffic peaks | Missing cache / slow queries | Object cache, DB indexes |
| Constant high CPU, low traffic | Malware / cryptominer | Audit processes, run malware scan |
| CPU spikes at specific hours | Overlapping cron jobs | Use flock, check task duration |
Best Practices to Prevent CPU Spikes
- Install a monitoring system (Netdata, Munin, or your provider's dashboard) and set email alerts when CPU exceeds 80% for more than 5 minutes.
- Enable full-page caching (WP Super Cache, Varnish, Nginx FastCGI Cache) to serve static content without hitting PHP.
- Configure PHP OPcache to avoid recompiling scripts on every request.
- Audit installed plugins regularly — abandoned or poorly coded ones are a common source of infinite loops.
- Run periodic security audits to rule out malware. Tools like
rkhunterorchkrootkittake only minutes.
If server maintenance is eating time you should spend on your business, elenlace.com offers VPS management and performance optimization services so you can focus on growing.
Key Takeaways
- High VPS CPU usage almost always has one specific process to blame;
topandps auxreveal it in seconds. - Root causes include bots, unindexed database queries, poorly optimized PHP scripts, and stacking cron jobs.
- Killing the process, blocking the IP, or fixing the query are the three levers for immediate relief.
- Long-term prevention depends on proactive monitoring, aggressive caching, and OPcache enabled.
- If load persists after optimization, the current VPS plan has outgrown your real traffic demands.
FAQ
How do I know if it's an attack or just legitimate traffic?
Check access logs: legitimate traffic shows a variety of IPs and diverse URL patterns. An attack or aggressive bot stands out — the same IP or range hitting the same URL dozens of times per second with an identical User-Agent string.
Can I limit CPU usage for a specific process?
Yes. With cpulimit you can set a ceiling: cpulimit -p <PID> -l 30 restricts that process to 30% of one core. You can also use cgroups for process groups, though the setup is more complex.
Does rebooting the server fix high CPU usage?
Only temporarily. If you don't identify and fix the root cause, the problem will return after the reboot. A restart is a last resort to restore service immediately — not a permanent fix.
How much CPU does a typical WordPress site need?
A properly cached WordPress site with fewer than 5,000 daily visits runs comfortably on 1–2 vCPU. Without caching, the same site can saturate 4 vCPU during a traffic spike. Full-page caching and OPcache make all the difference.
Prefer it done for you? El Enlace handles hosting and professional web development.
Compare providers
Other providers and guides worth comparing: