Operations 8 min read

Why Is My Linux Server CPU at 100%? Find the Culprit

A practical triage path for finding runaway processes, separating CPU pressure from I/O wait, and restoring a slow Linux server safely.

By BashPilot Team

Your Linux server is slow, requests are timing out, and top shows a process pinning the CPU at 100%. Before killing it, confirm whether the machine is actually CPU-bound. High load can also come from tasks blocked on storage, virtual machine steal time, or several scheduled jobs competing for the same resources.

Confirm whether the CPU is actually saturated

Start with overall utilization, the number of logical CPUs, and the load averages. On a four-core server, one single-threaded process can display 100% while three cores remain available. A load average near four may be manageable if tasks are running normally, while the same load can feel severe when several tasks are blocked in D state waiting for storage.

Capture the current CPU and load state
top -b -n 1
uptime
nproc

Compare the load averages with the logical CPU count. In the top output, inspect user, system, I/O wait, idle, and steal percentages.

Next, collect interval samples. The first line from vmstat represents averages since boot, so base your diagnosis on the later lines. mpstat is supplied by the sysstat package and shows whether pressure is spread across all CPUs or concentrated on one.

Measure CPU pressure over time
vmstat 1 10
mpstat -P ALL 1 5

Run as root if you need complete process visibility. Install the sysstat package if mpstat is unavailable.

MetricWhat it indicatesWhat to investigate
usTime executing application codeApplication workers, compression, scans, queries, or unexpected programs
syTime executing kernel codeHeavy networking, filesystem activity, drivers, or excessive system calls
waTime CPUs are idle while work waits for I/ODisk latency, storage saturation, backups, scans, or blocked mounts
stCPU time taken by the hypervisorAn overloaded virtualization host or an undersized VM plan
rTasks ready to runSustained values above the CPU count indicate a CPU run queue
bTasks blocked on I/OStorage, filesystem, network mount, or device problems

Find the process and thread consuming CPU

List processes by CPU use with their parent, state, priority, processor, age, and full command line. Repeat the sample several times. A process that appears once and disappears may be harmless, while the same process remaining at the top for minutes deserves investigation.

List the highest CPU consumers
ps -eo pid,ppid,user,stat,ni,psr,%cpu,%mem,etimes,comm,args --sort=-%cpu | head -n 25
pidstat -u -r -d -p ALL 1 5

pidstat separates CPU, memory faults, and disk activity for each process across repeated intervals.

A multi-threaded application can hide the hot worker behind one process name. Inspect its individual threads, then verify the executable and command line from /proc. This is especially useful when a generic name such as python3, java, or php-fpm appears at the top.

Inspect a suspected process
ps -L -p 12345 -o pid,tid,psr,stat,%cpu,%mem,comm --sort=-%cpu
readlink -f /proc/12345/exe
tr '\0' ' ' < /proc/12345/cmdline
lsof -p 12345 | head -n 40

Replace 12345 with the process ID. The executable, arguments, and open files help distinguish expected work from a broken worker or unknown program.

Find the owning systemd unit or container before taking action. A supervisor may immediately restart a killed worker, creating a loop that makes the incident worse.

Identify the service or container
systemctl status --no-pager 12345
cat /proc/12345/cgroup
docker stats --no-stream

The Docker command is relevant only on hosts running Docker. The cgroup path often identifies the systemd service or container responsible for the process.

Separate CPU pressure from disk I/O wait

If the server feels saturated but overall CPU use is moderate, look for processes in D state. These tasks are waiting inside the kernel and cannot handle signals until the underlying operation returns. Killing the process may therefore have no immediate effect.

Find tasks blocked in uninterruptible sleep
ps -eo state,pid,ppid,user,wchan:32,%cpu,%mem,comm,args | awk '$1 ~ /^D/'
iostat -xz 1 5

Use the later iostat samples. Check latency and queue depth together rather than treating disk utilization as a complete diagnosis.

I/O metricMeaningWarning pattern
awaitAverage request completion timeA sustained increase that matches application slowdown
aqu-szAverage queued requestsA growing queue while latency rises
%utilTime the device reports activeHigh activity combined with elevated latency and queue depth
r/s and w/sRead and write operations per secondA sudden change that lines up with a backup, scan, or workload spike

Do not rely on %util alone for SSD and NVMe devices, which can process requests concurrently. Elevated await, a persistent queue, blocked tasks, and visible application latency provide stronger evidence. If storage looks healthy, check st in vmstat next. High steal time means the hypervisor is withholding CPU, which cannot be fixed by terminating a guest process.

Reduce the load without killing the wrong process

First decide whether the process is expected. Compression, account backups, malware scans, package upgrades, database maintenance, and log rotation can all be legitimate. When two scheduled jobs overlap, lowering their CPU and I/O priority is often safer than stopping them halfway through.

Lower the priority of legitimate batch work
target_pid=12345
renice -n 10 -p "$target_pid"
ionice -c 2 -n 7 -p "$target_pid"

Replace 12345 with the process ID. This reduces contention but does not impose a hard resource limit.

If a service is malfunctioning, use its service manager or vendor control panel to stop it cleanly. When no supported control exists and termination is necessary, send SIGTERM, wait, and check whether it exited. Reserve SIGKILL for a confirmed process that cannot be stopped safely by another method.

Request a graceful process shutdown
target_pid=12345
kill -TERM "$target_pid"
sleep 5
ps -p "$target_pid" -o pid,stat,etime,cmd

If the process remains in D state, resolve the storage or mount problem instead of repeatedly sending signals.

For cPanel servers, avoid scheduling account backups and full malware scans in the same window. In the supplied incident, pkgacct, pigz, and cpbackup_transporter were processing the account serving bashpilot.com while Imunify360 workers were scanning concurrently. MySQL remained at a steady background level. The appropriate fix is to let one maintenance workload complete, reduce its priority if service latency is unacceptable, and move future backup and scan schedules apart.

Verify that the server recovered

Repeat the same measurements used during diagnosis. CPU idle time should recover, the run queue and blocked-task count should fall, disk latency should return toward its normal baseline, and the offending process should either complete or remain at its reduced priority. Also test the affected application, because improved system metrics do not prove that user-facing requests are healthy.

Recheck CPU, storage, and process activity
vmstat 1 10
iostat -xz 1 5
pidstat -u -d -p ALL 1 5
uptime

Load averages decay over time, so the one-minute value may remain elevated briefly after the immediate pressure has ended.

Check the service endpoint, error logs, and request latency as well. If CPU pressure returns at the same time each day, compare the recurrence with cron jobs, systemd timers, backup schedules, security scans, and database maintenance. A recurring pattern is usually easier to fix at the scheduler than at the process level.

After establishing this baseline manually, BashPilot can repeat the same read-only triage across supported Linux servers using vetted operations. If a destructive follow-up is proposed, it requires explicit approval, and any write is followed by verification.

In BashPilot

See how BashPilot separates CPU use from I/O pressure

app.bashpilot.com
Why is my Linux server CPU at 100%?
CPU and I/O assessment

The server is not currently at 100% CPU. The immediate bottleneck is disk contention caused by overlapping maintenance work. A cPanel backup for the account serving bashpilot.com is running at the same time as an Imunify360 malware scan. The backup process is blocked in D state while waiting for storage.

  • cPanel backup: pkgacct is using 68.6% CPU, pigz 28.3%, and cpbackup_transporter 27.9%.
  • Imunify360 scan: the scan runner is using 35% CPU, imunify360-pam 36.7%, and rustbolit 26%.
  • MySQL: steady at 13% CPU and 682 MB RSS, consistent with background database activity rather than the main bottleneck.
MetricObserved value
Total CPU utilization34% across 4 cores
Load averages2.17 / 1.86 / 1.96
I/O wait12%
Disk utilization59%
Disk queue depth3.07
Memory4.9 GB used of 15.8 GB
Swap2 GB used of 7.9 GB
Example output, not a screenshot of a specific customer's server.

Try this on one of your own servers.

Start free trial

Prevent the next CPU or I/O spike

  • Separate backup, compression, malware scanning, package maintenance, and database jobs into different scheduling windows.
  • Keep sysstat history so you can compare CPU, load, and storage activity from before the alert instead of relying on the current snapshot.
  • Alert on sustained CPU busy time, I/O wait, storage latency, and run-queue growth rather than on load average alone.
  • Apply service-level CPU or I/O controls to repeat offenders only after measuring their normal resource needs.
  • Investigate long uptimes and pending kernel updates during a planned maintenance window, not during an active performance incident.
Collect a short performance baseline
sar -u 1 5
sar -q 1 5
sar -d 1 5

Save representative healthy and busy samples. Your own baseline is more useful than a universal threshold.

Share LinkedIn X
Questions

Frequently asked questions

Why does top show a process at 100% on a four-core server?

On Linux, a process at 100% usually consumes the capacity of one logical CPU. A four-core server has roughly 400% of process-level CPU capacity available. Check the overall CPU summary and per-CPU view before concluding that the entire machine is saturated. Multi-threaded processes can exceed 100% by running on several logical CPUs.

Can Linux load average be high when CPU usage is low?

Yes. Linux load average includes tasks ready to use CPU and tasks in uninterruptible sleep, commonly shown with state `D`. Storage latency, a blocked network filesystem, or device trouble can therefore raise load while CPU idle time remains available. Use `vmstat`, `iostat`, and the process state column together to distinguish CPU pressure from blocked I/O.

Does high I/O wait mean the CPU is overloaded?

Not necessarily. I/O wait means a CPU had no runnable task while at least one operation was waiting for I/O. It often indicates that application progress is limited by storage, but the underlying cause must be confirmed with latency, queue depth, blocked processes, and workload activity. A backup and malware scan running together are a common example.

Is it safe to use kill -9 on the process using the most CPU?

No. `SIGKILL` prevents the process from performing cleanup and cannot stop a task immediately if it is blocked in uninterruptible sleep. Identify the owning service and workload first, then use the service manager or send `SIGTERM`. Abruptly killing a database, backup, package manager, or filesystem process can leave incomplete or inconsistent state.

Put your servers on autopilot.

Connect a server in about a minute. The first week is on us.