Skip to main content

Calculating CPU Usage from /proc/stat

· 3 min read

I recently came across a number of forum topics asking how to calculate CPU usage from /proc/stat, which raised a very slight sense of challenge within me (was just in "the mood" to do some Bash scripting)... so, here's an example showing how to calculate CPU usage with a simple Bash script.


Note, the following script has been moved to github:

So check there for the latest version.

# by Paul Colby (, no rights reserved ;)


while true; do
CPU=(`cat /proc/stat | grep '^cpu '`) # Get the total CPU statistics.
unset CPU[0] # Discard the "cpu" prefix.
IDLE=${CPU[4]} # Get the idle CPU time.

# Calculate the total CPU time.
for VALUE in "${CPU[@]}"; do

# Calculate the CPU usage since we last checked.
echo -en "\rCPU: $DIFF_USAGE% \b\b"

# Remember the total and idle CPU times for the next check.

# Wait before checking again.
sleep 1

The script should be pretty self-explanatory. It loops forever (just hit Ctrl-C when you want it to stop). Each time through the loop, it calculates the CPU usage by subtracting the CPU's "idle" time from the CPU's "total" time. Notice the way the percentage is calculated by multiplying by 1000, and then dividing by 10 at the end, instead of the "normal" approach of multiplying by 100. This is actually a cunning way of rounding off :) See the way I add 5 just before the divide by 10? So, for example, if the percentage was 45.6% then Bash would truncate the result to 45%. But, by multiplying by 1000 (instead of 100), and adding 5, the result is 461 (ie 456+5), which, when divided by 10 at the end, yields the correctly rounded result of 46% :) The other neat trick in the above script is the output "echo" statement:

echo -en "\rCPU: $DIFF_USAGE%  \b\b"

This causes the script to output the CPU % on just one line - ie continually overwriting the previous value. It works like this:

  • the -e parameter causes the echo command to interpret the \r and \b escape codes;
  • the -n parameter prevents the echo command from appending the usual carriage-return to the end of the line;
  • the two spaces after the % sign are there to overwrite previous characters that would be left over when going from double (or triple) digits down to single (or double) digits;
  • and finally, the two \b (backspace) codes put the cursor back to being immediately after the % symbol, otherwise the the two spaces above kinda leave the cursor hanging in the middle of nowhere.

Well, that's it. Any questions, or suggestions, add a comment below :)