Bootstrap FreeKB - Linux Fundamentals - High CPU on Linux
Linux Fundamentals - High CPU on Linux

Updated:   |  Linux Fundamentals articles

When a Linux system is experiencing high CPU, I typically start with the top command.

By default, top is real time, meaning that the top output will refresh every few seconds. The -n 1 option can be used to display a snap shot of top.

top -n 1

 

Sometimes, simply issuing the top command will spot one or more processings using the majority of the CPU. In this example, a Java process is using 90% of the CPU.

PID    User   PR  NI     VIRT     RES     SHR   S  %CPU  %MEM    TIME+   COMMANDS
4594   root   20   0   417768  144754    5803   S  90.0   5.2  0:41:49       Java

 

It's important to recognize the Linux system may have more than 1 CPU core. The nproc command can be used to list the number of CPU cores the Linux system is using.

~]# nproc
4

 

In this example, since the Linux system has 4 CPU cores, the max CPU for the system is 400%, thus if a process is using 100% CPU, that's only 25% of the total available CPU.

Here is my go-to script for capturing CPU once every 5 seconds.

#!/bin/bash
IFS=$'\n'

log_file="/tmp/cpu.log"

while true; do
    # Get number of CPU cores
    cpu_cores=$(nproc)
    echo "[$(date '+%m/%d/%Y %H:%M:%S.%s')] Server has $cpu_cores CPU cores" | tee --append $log_file

    # Get overall CPU usage (100% per core, so divide by cores to get real percentage)

    cpu_idle=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/")
    cpu_used=$(echo "100 - $cpu_idle" | bc)
    echo "[$(date '+%m/%d/%Y %H:%M:%S.%s')] Overall CPU usage: ${cpu_used}% (${cpu_idle}% idle)" | tee --append $log_file

    # Calculate threshold: if a process uses more than (100/cores)%, it's using more than 1 full core
    threshold_per_core=$(echo "100 / $cpu_cores" | bc)
    echo "[$(date '+%m/%d/%Y %H:%M:%S.%s')] Threshold per core: ${threshold_per_core}% (processes above this are using 1 or more full cores)" | tee --append $log_file

    cpu=$(ps aux --sort=-%cpu | awk -v thresh="$threshold_per_core" 'NR==1 || $3 > thresh')

    # Count the number of lines in the cpu variable
    cpu_line_count=$(echo "$cpu" | wc -l)

    if [ "$cpu_line_count" -eq 1 ]; then
        echo "[$(date '+%m/%d/%Y %H:%M:%S.%s')] There are no processes currently using more than ${threshold_per_core}% CPU (threshold per core)" | tee --append $log_file
    else
        echo "[$(date '+%m/%d/%Y %H:%M:%S.%s')] Processes using more than 1 full CPU core (>${threshold_per_core}%):" | tee --append $log_file

        for line in $cpu; do
            echo "[$(date '+%m/%d/%Y %H:%M:%S.%s')] $line" | tee --append $log_file
        done
    fi
    
    sleep 5
done

 

Running this script will return stdout and append lines to the log file like this.

[02/10/2026 13:18:41.1770751121] Server has 2 CPU cores
[02/10/2026 13:18:41.1770751121] Overall CPU usage: 6.2% (93.8% idle)
[02/10/2026 13:18:41.1770751121] Threshold per core: 50% (processes above this are using 1 or more full cores)
[02/10/2026 13:18:41.1770751121] There are no processes currently using more than 50% CPU (threshold per core)

 

One common cause of high CPU is a cron job that runs commands that cause high CPU. Check your cron table (crontab) to see if a scheduled job correlates to the time when there is high CPU. For example, perhaps a crontab job is creating gzip or bzip2 compressed archives of a certain directory, such as /etc, which may cause high CPU while the job is running.

Another cause of high CPU is an application that is doing something to use a lot of CPU. For example, if you have a web server (apache httpd ngnix) or an application server (tomcat websphere) installed on the system, the web app may be using excessive CPU.




Did you find this article helpful?

If so, consider buying me a coffee over at Buy Me A Coffee



Comments


Add a Comment


Please enter 239f7c in the box below so that we can be sure you are a human.