VPS High CPU Usage: How to Find and Kill the Offending Process
A VPS running at 100% CPU makes your server unresponsive, slows SSH login to a crawl, and often triggers OOM kills. The fix is almost always identifying the culprit process and deciding what to do with it.
Step 1: See What Is Using CPU Right Now
top
Press P to sort by CPU usage (default). The process at the top is your heaviest consumer.
For a cleaner output:
ps aux --sort=-%cpu | head -20
This shows the top 20 processes sorted by CPU descending. Note the PID (second column) and the command name (last column).
Step 2: Identify the Process
# Full command line — shows exact binary and arguments
cat /proc/PID/cmdline | tr '\0' ' '
# Which user owns it
ls -la /proc/PID/exe
# Open files and network connections
ls -la /proc/PID/fd | head -20
Replace PID with the actual process ID from Step 1.
Common High-CPU Culprits on VPS
| Process | Likely Cause | Action |
|---|---|---|
php-fpm, nginx, apache2 | Traffic spike or slow query | Check access logs, add rate limiting |
mysqld / mariadb | Slow/unindexed queries | Run SHOW PROCESSLIST; in MySQL |
python, node | Runaway script or infinite loop | Review your application code |
Unknown binary in /tmp | Cryptominer malware | Kill immediately, investigate |
kswapd0 | Out of memory, excessive swapping | Add swap or upgrade RAM |
cc1, make | Build/compile job | Expected; let it finish or kill if unintended |
Step 3: Kill the Process
If the process is malicious or runaway:
# Graceful termination
kill PID
# Force kill (if process ignores SIGTERM)
kill -9 PID
If it is a systemd service that keeps restarting:
systemctl stop SERVICE_NAME
systemctl disable SERVICE_NAME
Step 4: Investigate a Suspected Cryptominer
High CPU from an unknown process in /tmp, /var/tmp, or with a random-looking name is almost always a cryptominer dropped via a compromised service.
Signs:
- Binary in a world-writable temp directory
- Process name does not match anything you installed
- High network I/O alongside high CPU
- Connection to mining pool IPs
Immediate response:
# Kill the process
kill -9 PID
# Find related files
find /tmp /var/tmp /dev/shm -type f -perm /111 2>/dev/null
# Check crontabs for persistence
crontab -l
cat /etc/cron.d/*
cat /var/spool/cron/crontabs/*
# Check for unauthorized SSH keys
cat ~/.ssh/authorized_keys
After cleaning up, audit how the attacker got in (check auth logs, web server logs, application versions) and patch the entry point. Consider taking a snapshot before cleanup for forensic purposes.
Step 5: Prevent Recurrence
Rate limiting nginx:
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
MySQL slow query log:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
Add a swap file to prevent OOM kills on memory-constrained VPS:
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
Resource limits per user via /etc/security/limits.conf:
www-data soft nproc 100
www-data hard nproc 200
If you consistently need more CPU headroom, VMHeaven's Hi-CPU plans offer higher single-core clock speeds — better for CPU-bound workloads than adding more vCPUs.