Know how much an individual process or system-wide consume CPU or memory. As a sysadmin, you often have to deal with an incident where the application is slow or unresponsive due to high CPU/memory/network utilization. If the server host just one process, then it’s easy to find out when the process consumes all the resources. However, imagine a shared server where multiple services are running, and you need to find which one is eating all the resources. There are many monitoring software which does this out of the box. But if you don’t have one or looking for a command-based solution, then here you go. They are all FREE!


You may want to start by looking into top or htop result to see the processes overview. As you can see below, it gives an excellent idea about what all processes are utilizing. If you look at the first one, which is MySQL is taking 11.9% of CPU and 2.5% of CPU.

top - 11:57:33 up 0 min, 1 user, load average: 3.69, 0.96, 0.32 Tasks: 165 total, 2 running, 113 sleeping, 0 stopped, 0 zombie %Cpu(s): 21.0 us, 5.5 sy, 0.0 ni, 70.5 id, 1.7 wa, 0.0 hi, 1.3 si, 0.0 st KiB Mem : 7637308 total, 5802888 free, 849512 used, 984908 buff/cache KiB Swap: 0 total, 0 free, 0 used. 6495648 avail Mem  PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND  1986 netdata 20 0 1738856 191560 22948 S 11.6 2.5 0:02.30 mysqld  3021 www-data 20 0 255288 78420 55484 S 6.6 1.0 0:01.55 php-fpm  3138 www-data 20 0 253096 79780 59228 S 6.6 1.0 0:00.92 php-fpm  3153 www-data 20 0 255116 79088 56472 S 5.0 1.0 0:00.70 php-fpm  3037 www-data 20 0 257200 81088 56216 S 4.3 1.1 0:01.50 php-fpm  3048 www-data 20 0 257088 78740 55380 S 4.3 1.0 0:01.46 php-fpm  3054 www-data 20 0 254160 72168 52108 S 3.7 0.9 0:01.32 php-fpm  3135 www-data 20 0 255084 75912 54836 S 3.7 1.0 0:00.91 php-fpm  3051 www-data 20 0 254096 73804 51964 S 3.0 1.0 0:01.38 php-fpm  2962 www-data 20 0 45280 7284 3488 R 2.0 0.1 0:00.22 openresty  1062 netdata 20 0 338748 76144 6720 S 1.0 1.0 0:01.31 netdata  1702 netdata 20 0 21852 4232 2352 S 1.0 0.1 0:00.34 apps.plugin  1729 netdata 20 0 18636 3280 2764 S 0.7 0.0 0:00.05 bash  1980 netdata 20 0 62008 12896 5796 S 0.7 0.2 0:00.14 redis-server  11 root 20 0 0 0 0 I 0.3 0.0 0:00.14 rcu_sched  1007 root 20 0 1347424 74524 38872 S 0.3 1.0 0:00.92 dockerd  1857 root 20 0 10600 5564 4276 S 0.3 0.1 0:00.03 containerd-shim  2045 root 20 0 9948 6028 5016 S 0.3 0.1 0:00.14 forego  2934 root 20 0 13616 8760 5928 S 0.3 0.1 0:00.07 docker-gen  2966 systemd+ 20 0 25784 7924 2340 S 0.3 0.1 0:00.06 nginx

The top is installed on almost all Linux distribution. Once you identify the suspect, then you may want to focus on that process instead of everything like you saw above. You can still use top command but with some argument. Let’s say you know the process id (PID); you can use the below command. top -p $PID Below an example of top -p 3102

top - 11:59:56 up 3 min, 1 user, load average: 0.72, 0.70, 0.31 Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie %Cpu(s): 7.1 us, 2.9 sy, 0.0 ni, 89.1 id, 0.3 wa, 0.0 hi, 0.7 si, 0.0 st KiB Mem : 7637308 total, 5802024 free, 783672 used, 1051612 buff/cache KiB Swap: 0 total, 0 free, 0 used. 6555636 avail Mem  PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND  3102 www-data 20 0 329500 82376 60640 S 0.0 1.1 0:03.35 php-fpm

You may also use grep with top. Below an example of checking Docker utilization.

[email protected]:~# top | grep docker 1007 root 20 0 1347424 74524 38872 S 0.3 1.0 0:01.38 dockerd  2934 root 20 0 14676 9652 5928 S 0.3 0.1 0:00.54 docker-gen  1007 root 20 0 1347424 74524 38872 S 0.3 1.0 0:01.39 dockerd  1007 root 20 0 1347424 74524 38872 S 1.0 1.0 0:01.42 dockerd  2934 root 20 0 14740 9652 5928 S 0.3 0.1 0:00.55 docker-gen  2934 root 20 0 14740 9652 5928 S 0.3 0.1 0:00.56 docker-gen


Similar to the top but with more information. As you can, it got the command column, which is handy to identify the process path. And also it is colorful. htop may not be installed by default, but you can always do it as below.

Install htop on Ubuntu

apt-get install htop

Install htop on CentOS/RHEL 8.x

dnf install dnf update dnf install htop


As the name says, you get a system utilization view on a single screen. Running processes are sorted by their CPU utilization. You can install glances on CentOS 8 using DNF as below.

dnf install glances

for CentOS7, you can use YUM

yum install glances


A similar to the above listed but with a brilliant feature to record the output in a file so you can view them later. Imagine there is a pattern of having an issue at a specific time window. You can schedule to write the output in a file through crontab or other, and later you can playback. To record the output in a file:

atop -w filename

and, to playback:

atop -r filename

It supports multiple arguments like interval, samples, etc. and I would strongly recommend taking a look at the man page. If you are just interested in real-time troubleshooting, then just execute atop and you should see like below. You can install atop as below.

dnf install atop


Let’s check ps command now. You can use the ps command with PID to print their CPU and memory utilization.

ps -p $PID -o %cpu,%mem

The output should look like this.

[email protected]:~# ps -p 1048 -o %cpu,%mem %CPU %MEM 0.2 3.0 [email protected]:~#


Interactive command-line monitoring tool for CPU, memory, disks, network, NFS, and virtual memory utilization. To view the top process (by utilization), you can execute nmon and press t button. You can install nmon as below.

dnf install nmon


Monit is a web-based and command-line open-source solution to monitor server resources, daemons, files, directory, file systems, etc. Monit also got a cool widget. YouTube video Its light-weight monitoring software. But, there is more to explore here.


A lightweight open-source utility to monitor the Linux server. Monitorix got in-built HTTP so you can check the utilization and other stuff on the web. Some of the other usage reports include:

  • Kernal/temperature
  • Filesystem and I/O
  • Network traffic
  • Apache/Mail/FTP/Nginx
  • MySQL/Varnish/Memcached

Monitorix also offers alert configuration so you can get notified when things are not right. It will be a good choice when you are managing cloud-based servers and looking for a proactive monitoring solution.

Network data

Netdata is a real-time performance monitoring for system resources, applications, web servers, databases, DNS, mail, hardware sensors, and a lot more. It is open-source and getting started is easy. All the data is collected, stored, and streamed for you to visualize interactively. Data is collected every second, so you never miss anything. Loved by many industry leaders. So what you are waiting for, try and take control of your Linux servers.


btop is a handy resource monitor fully interactive with a beautiful UI helping you manage the Linux servers. btop: linux resource monitor You can easily visualize the processes in a tree view, filter from the process list, and manage the resource hogs. btop also comes powered with an auto-scaling graph showing network usage. Besides, you can also check disk speed and complete I/O activity. There is more to this that you can experience on Linux, FreeBSD, and macOS.


I hope the above tools help you to visualize the server utilization in real-time so you can take necessary action. If you just started as a system administrator and looking to get hands-on training, then check out this Udemy course.

1. Overview

We often need to get or monitor resource usage by currently running processes in the Linux command line. When we’re facing this kind of requirement, two handy commands may come up: the ps command and the top command. By default, they will list the resource usages of all processes that the current login user can see. However, sometimes, we would like to periodically log the resource usage, such as CPU usage, of a specific process. This tutorial will discuss the best way to do that.

2. Introduction to the Problem

Let’s say we want to write the CPU usage of a specific process every two seconds into a log file so that we can analyze the data later. We will build our solutions based on the ps and top commands. To make our test easier, let’s take the mpv media player and play an HD movie to simulate a long-running and random CPU-consuming target process.

3. CPU Usage: ps vs. top

We know that both the ps and top commands can report the CPU usage of processes. Before we start looking at how to get CPU usages of a single process using these commands, we should first understand how the two commands calculate their CPU usage data. This is important because their CPU usage values have different meanings.

3.1. Understanding CPU Usage With the ps Command

Let’s take a look at the ps command first. The ps command reports a snapshot status of current processes. However, its CPU usage value isn’t the real-time usage metric of the time point we execute the command. Instead, the CPU usage provided by the ps command is expressed as the percentage of time spent running during the entire lifetime of a process. So, in other words, it’s the average CPU usage of a process over the time it has been running. Next, let’s take a look at how the top command calculates its CPU usage value.

3.2. Understanding CPU Usage With the top Command

Unlike the ps command, the top command can show detailed information of processes in an interactive user interface. In addition, it refreshes the result in an interval that we can define using the -d option. It calculates the CPU usage value in a different way from the ps command. The top command calculates the elapsed CPU time since the last screen update, expressed as a percentage of total CPU time. For example, suppose we set two seconds as the refresh interval, and the CPU usage reports 50% after a refresh. The usage value “50%” means in the last two seconds, the accumulated CPU running time for the process is one second. Despite both ps and top reporting the CPU usage value in a percentage form, the meanings are different. Therefore, we should choose the right tool depending on the requirement. Otherwise, our analysis based on the logged data may go in the wrong direction.

4. Writing the CPU Usage to a Log File Every Two Seconds

Now, we’ll address how to create ps- and top-based shell scripts to write the CPU usages of a given process into a log file. As we’ve said earlier, we’ll take the running mpv process as an example. Also, we’ll skip the argument check and error handling parts in our example scripts.

4.1. Building a Shell Script Based on the ps Command

We can use the command “ps -C PROCESS_NAME -o %cpu” to retrieve the CPU usage of the given process, for example:

$ ps -C mpv -o %cpu %CPU 63.8 

We can build a simple shell script to write the CPU usage to a log file every two seconds:

$ cat ./ #!/bin/bash PNAME="$1" LOG_FILE="$2" while true ; do echo "$(date) :: $PNAME[$(pidof ${PNAME})] $(ps -C ${PNAME} -o %cpu | tail -1)%" >> $LOG_FILE sleep 2 done 

The script above expects two arguments: a process name and a log file path. We put the logging implementation in a “while true…“. Therefore, when we start the script, it’ll keep writing CPU usage of the given process to the log file until we terminate it manually. Also, we write the current time “$(date)”, process name and PID “$PNAME[$(pidof ${PNAME})]” together with the CPU usage data to the log file. Next, let’s start the script:

$ ./ mpv /tmp/log_ps.txt

Then, we can monitor the changes of the log file using the tail -f command:

$ tail -f /tmp/log_ps.txt Fri Sep 3 10:05:08 PM CEST 2021 :: mpv[215406] 40.9% Fri Sep 3 10:05:10 PM CEST 2021 :: mpv[215406] 40.9% Fri Sep 3 10:05:12 PM CEST 2021 :: mpv[215406] 41.0% Fri Sep 3 10:05:14 PM CEST 2021 :: mpv[215406] 41.1% Fri Sep 3 10:05:16 PM CEST 2021 :: mpv[215406] 41.2% Fri Sep 3 10:05:18 PM CEST 2021 :: mpv[215406] 41.2% ...

As the output shows, our script has written CPU usages of the mpv process to the specified log file every two seconds.

4.2. Using the top Command to Print the Status of a Single Process in Batch Mode

Usually, the top command will start in an interactive interface mode to show the process status. However, the -b option tells the top command to run in a batch mode to redirect the output to a log file. Furthermore, we need to set the refresh interval by using the -d option. For example, we can make the top command keep reporting the status of the mpv process every two seconds until we manually kill it:

$ top -b -d 2 -p $(pidof mpv) top - 21:26:39 up 1 day, 12:05, 1 user, load average: 1.42, 1.35, 1.34 Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie %Cpu(s): 5.3 us, 4.8 sy, 1.6 ni, 87.2 id, 0.0 wa, 0.5 hi, 0.5 si, 0.0 st MiB Mem : 31891.0 total, 6762.8 free, 10898.7 used, 14229.6 buff/cache MiB Swap: 0.0 total, 0.0 free, 0.0 used. 16885.9 avail Mem  PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 185292 kent 20 0 3077452 282804 82880 S 56.7 0.9 2:01.35 mpv top - 21:26:41 up 1 day, 12:05, 1 user, load average: 1.47, 1.36, 1.35 ( ... summary omitted ... ) PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 185292 kent 20 0 3077452 283332 82880 S 58.0 0.9 2:01.41 mpv top - 21:26:43 up 1 day, 12:05, 1 user, load average: 1.47, 1.36, 1.35 ( ... summary omitted ... ) PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 185292 kent 20 0 3077452 284124 82880 S 57.0 0.9 2:01.47 mpv top - 21:26:45 up 1 day, 12:05, 1 user, load average: 1.43, 1.36, 1.34 ( ... summary omitted ... ) PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 185292 kent 20 0 3077452 284916 82880 S 53.5 0.9 2:01.54 mpv ^C

As the output above shows, the top command prints the process status every two seconds. We’ve terminated the top command by pressing Ctrl-C after four iterations. According to this problem, we only need the CPU usage data. Therefore, we need to extract the timestamp and the CPU usage from this output.

4.3. Building a Shell Script Based on the top Command

awk is a powerful weapon for processing text. So, let’s pipe the top output to an awk command to solve the problem:

$ cat #!/bin/bash PNAME="$1" LOG_FILE="$2" PID=$(pidof ${PNAME}) top -b -d 2 -p $PID | awk \ -v cpuLog="$LOG_FILE" -v pid="$PID" -v pname="$PNAME" ' /^top -/{time = $3} $1+0>0 {printf "%s %s :: %s[%s] CPU Usage: %d%%\n", \ strftime("%Y-%m-%d"), time, pname, pid, $9 > cpuLog fflush(cpuLog)}'

The script isn’t hard to understand. The awk command extracts the required data from the top output and redirects to the log file. We should note that at the end of the awk command, we must call the fflush function to write any new output into the log file. Otherwise, it’ll buffer the output, and we may lose data when we kill the script manually. Now, let’s give this script a try. First, we start the script and pass mpv and the log file /tmp/log_top.txt as arguments:

$ ./ mpv /tmp/log_top.txt

Similarly, we move to the log file and check if our script writes the expected data in it every two seconds:

$ tail -f /tmp/log_top.txt 2021-09-03 22:14:37 :: mpv[215406] CPU Usage: 40% 2021-09-03 22:14:39 :: mpv[215406] CPU Usage: 43% 2021-09-03 22:14:41 :: mpv[215406] CPU Usage: 40% 2021-09-03 22:14:43 :: mpv[215406] CPU Usage: 54% 2021-09-03 22:14:45 :: mpv[215406] CPU Usage: 57% 2021-09-03 22:14:47 :: mpv[215406] CPU Usage: 56% ... 

As we can see, our script works as expected.

5. Conclusion

In this article, we’ve addressed building simple shell scripts to log the CPU usages of a single process. Further, we’ve discussed why the CPU usage values from ps and top have different meanings. We should choose the right tool depending on the requirement. If you have a few years of experience in the Linux ecosystem, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines. top utility displaying current CPU usage for each running process The top utility displays current CPU usage for each running process, but what if you wanted to monitor this over time and display it on a graph? There are a few utilities for this if your cloud provider doesn’t have one already. As a side note, if you don’t have it installed already, the htop utility (pictured above) is a lot nicer to use than default top.

The Trivial Solution: Use Your Cloud Provider’s Graphs

This solution is by far the easiest to use, but it won’t be available for everyone. If you’re on AWS, CloudWatch makes monitoring CPU usage very easy. From the CloudWatch Management Console, you select “Metrics” and then view metrics for EC2. The “CPUUtilization” metric displays your average CPU utilization: In the CloudWatch Management Console, select "Metrics" and then view metrics for EC2. Your average CPU utilization is measured in 5-minute increments, but you can enable extended monitoring for the instance and bump it up to 1-minute increments. Doing so does cost extra though. You’re also able to easily set alarms for when CPU usage gets too high as well. If you’re on Google Cloud Platform, a graph appears under the “Monitoring” tab when you select an instance. Graph that appears on Google Cloud Platform under the "Monitoring" tab when an instance is selected. Azure has Azure Monitor, which displays similar info: Azure Monitor displays similar info as Google Cloud Platform. For most other cloud providers, they’ll likely have a graph like this as well.

Using /proc/loadavg

The best way to do this natively is to look at where top gets its information from. /proc/loadavg contains 1-minute, 5-minute, and 15-minute averages. You can log it with cat

cat /proc/loadavg/ 1.71 1.32 1.38 2/97 6429

You can use this to generate a graph by printing each line into a comma-seperated CSV file, using some awk magic:

cat /proc/loadavg | awk '{print $1","$2","$3}' >> cpu.csv

Hook this up to a cron job running every minute, rotate logs with logrotate, and you’ve got yourself a jerry-rigged CPU monitor. You can import the CSV file into Excel, where it will be easy to graph the average CPU utilization on a line chart. Note, the above command prints the 1-minute, 5-minute, and 15-minute averages. If you’re running it every minute, it’s not really necessary to print the 5- and 15-minute averages, because you can figure that out computationally.

Install sysstat

The sar utility is great for monitoring system performance. It’s included as part of sysstat, which is probably not installed by default on your system. You’ll have to get it from your distro’s package manager. For Debian-based systems like Ubuntu, it would be:

sudo apt-get install sysstat

Next, enable it by editing /etc/default/sysstat and setting “ENABLED” to true. Doing so monitors your system and generates a report every 10 minutes, rotating them out after a week. You can modify this behavior by editing the sysstat crontab at /etc/cron.d/sysstat, or by changing rotation settings in the sysstat settings at /etc/sysstat/sysstat. You can generate a real-time report with the following command:

became -u 1 3

sysstat will collect background CPU usage data every minute, saving it to /var/log/sysstat/. You can then import this data for analysis, using either a spreadsheet program or a custom tool like sargraph, which displays a nice chart: sargraph displays a chart of CPU usage. You can also use command line utilities for plotting graphs like this, such as ttyplot, but none of them come close to being as easy to use (and as nice looking) as a GUI. The command line is beat on this one—charts are nicer.

Monit Can Alarm You If CPU Usage Is Too High

Monit logo Monit is a open source monitoring suite for Unix that checks the health of your server and can be configured to send you notifications if your server’s CPU usage becomes dangerously high. Read our guide to setting it up to learn more. Note that CloudWatch achieves the same thing out of the box with alarms, and it can operate on multiple different metrics, not just CPU usage. READ NEXT

  • › How to Use Microsoft Excel Templates for Event Planning
  • › How Much Money Does Upgrading to LED Christmas Lights Save?
  • › Astronomers Discover Closest Black Hole to Earth (Which is Still Far)
  • › How to Use Your Car as an Emergency Electricity Source During a Blackout
  • › How to Sign Out of Google on All Your Devices
  • › StumbleUpon Made the Internet Feel Small

Leave a comment

Your email address will not be published. Required fields are marked *