1. Overview

It’s quite common to find ourselves in a situation where we need to know the resource usage of each process and thread in our system. For example, we might want to know which process is slowing down a given environment.

In this tutorial, we’ll look at how to get this and other insights using the top command.

2. top Interface

To begin with, we can use top by simply typing top in the command line, after which we get an interactive interface:

top

top - 04:05:27 up 3 days, 12:02,  1 user,  load average: 0.55, 1.06, 1.27
Tasks: 362 total,   2 running, 290 sleeping,   0 stopped,   0 zombie
%Cpu(s): 35.8 us, 10.7 sy,  0.0 ni, 52.4 id,  0.3 wa,  0.0 hi,  0.7 si,  0.0 st
KiB Mem :  8060436 total,   150704 free,  4438276 used,  3471456 buff/cache
KiB Swap:  2097148 total,  1656152 free,   440996 used.  2557604 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
32081 abhishe+  20   0  879676 198164 106096 S 152.6  2.5   0:10.16 chrome
  582 abhishe+  20   0   51448   4088   3372 R  15.8  0.1   0:00.04 top
  503 root     -51   0       0      0      0 S   5.3  0.0  11:05.61 irq/130-iwlwifi
  875 message+  20   0   53120   5900   3204 S   5.3  0.1  10:10.14 dbus-daemon
 6855 abhishe+  20   0 1564544 170444  22924 S   5.3  2.1  75:21.88 deluge-gtk
    1 root      20   0  225840   7200   4720 S   0.0  0.1   4:51.28 systemd
    2 root      20   0       0      0      0 S   0.0  0.0   0:00.20 kthreadd
    4 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 kworker/0:0H
    6 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 mm_percpu_wq

This interactive screen is divided into four sections:

  1. Summary
  2. Fields/Columns Header
  3. Input/Message Line
  4. Tasks

Let’s explore some of the main parts.

3. System Overview Headers

Let’s understand the header portion of top.

The first line consists of five pieces of data:

  1. name of the window
  2. current time
  3. length of time since last boot
  4. total number of users
  5. system load averaged over the last 1, 5, and 15 minutes
top - 04:05:27 up 3 days, 12:02, 1 user, load average: 0.55, 1.06, 1.27

We can see that the second line gives the count of various processes and threads, divided into four categories: running, sleeping, stopped, and zombie.

Next, the third line tells us about the CPU state percentage, that is, the time taken by user and kernel processes:

Tasks: 362 total, 2 running, 290 sleeping, 0 stopped, 0 zombie
%Cpu(s): 35.8 us, 10.7 sy, 0.0 ni, 52.4 id, 0.3 wa, 0.0 hi, 0.7 si, 0.0 st

Specifically, the acronyms in the above example follow the time taken by the CPU when running this kind of process:

  • us – user processes (that are defined without any user-defined priority – un-niced user processes)
  • sy – kernel processes
  • ni – niced user processes
  • id – kernel idle handler
  • wa – I/O completion
  • hi – hardware interrupts
  • si – software interrupts
  • st – time stolen from this VM by the hypervisor

We can notice that the fourth line describes the state of physical memory, while the fifth line describes the virtual memory:

KiB Mem : 8060436 total, 150704 free, 4438276 used, 3471456 buff/cache
KiB Swap: 2097148 total, 1656152 free, 440996 used. 2557604 avail Mem

In addition to this general overview, we can see some more specific information in column view.

4. Column Categories

As we can see in the example given above, there are various fields describing the status of processes and threads.

4.1. General Fields

Let’s learn about the meaning of these headers one by one:

  • PID (Process ID): unique id of the task that is defined by task_struct, used by the kernel to identify any process
  • USER (User Name): effective username of the task’s owner
  • PR (Priority): scheduling priority of the task with the rt values under this field meaning that the task is running under real-time scheduling prioritization
  • NI (Nice Value): priority of the task
  • TIME+ (CPU Time): total CPU time the task has used since it started with a granularity of hundredths of a second
  • %CPU (CPU Usage): task share of the elapsed CPU time since the last screen update, expressed as a percentage of total CPU time
  • COMMAND (Command Name): command line used to start a task or the name of the associated program

The difference between PR and NI is that PR is the real priority of a process as seen by the kernel, while NI is just a priority hint for the kernel. A negative nice value means higher priority, whereas a positive nice value means lower priority.

When it comes to the %CPU field, a value greater than 100% can be reported for a multi-threaded process when top is not running in Threads Mode.

4.2. Memory Fields

The headers that are used to summarize various parameters related to memory are described below:

  • VIRT (Virtual Memory Size in KiB): total amount of virtual memory used by the task
  • RES (Resident Memory Size in KiB): subset of the virtual memory space (VIRT) representing the non-swapped physical memory a task is currently using
  • SHR (Shared Memory Size in KiB): subset of resident memory (RES) that may be used by other processes
  • %MEM (Memory Usage -RES): current task share of available physical memory

Notably, virtual memory includes all code, data, and shared libraries. It also includes pages that have been swapped out and pages that have been mapped but not used.

5. Interactive Commands

The basic interaction with the top interface involves several keys:

  • h brings up the help menu
  • d or s change the refresh rate of top (default is 3 seconds)
  • q exits the interface

Additionally, we can kill a task by pressing the k button, which activates the Input Line, so we can enter the PID of the task to kill.

Furthermore, we can also change the renice value of a task by pressing the r button. After that, we enter the PID and then the renice value of that task. Ordinary users can only increase the nice value and are prevented from lowering it.

We can change the unit used for showing memory in the Summary Area from KiB by pressing E:

MiB Mem : 7871.520 total,  995.176 free, 4501.594 used, 2374.750 buff/cache
MiB Swap: 2047.996 total, 1607.332 free,  440.664 used. 2275.230 avail Mem

To change the memory unit used in the Task Area, we can press e:

22011 abhishe+  20   0 4049.7m 266.1m 138.3m S  13.2  3.4  18:08.67 gnome-shell
  920 cyberea+  20   0 2545.5m 110.4m   8.6m S   7.9  1.4  92:37.54 cybereason-sens
 1554 abhishe+  20   0  489.2m  69.9m  53.0m S   6.6  0.9  97:43.26 Xorg
 6855 abhishe+  20   0 1536.8m 174.6m  21.6m S   6.6  2.2  85:00.29 deluge-gtk
23393 abhishe+  20   0 1689.2m 197.4m  63.4m S   6.0  2.5   3:09.83 _Postman

Both of these lead to the cycling of memory units starting from KiB and going all the way up to EiB (exbibytes).

5.1. Global Modes

Different top modes are useful in various cases.

For example, we can use Threads Mode. By default, top displays a summation of all threads in each process. However, we can change this by pressing the H button. After this, top displays individual threads for each process:

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
 6855 abhishe+  20   0 1573660 178760  22124 S  2.6  2.2  45:11.77 deluge-gtk
 6899 abhishe+  20   0 1573660 178760  22124 S  2.3  2.2  37:41.68 deluge-gtk

As we can notice in the previous example, the application named deluge was mentioned only once as the underlying threads were not shown, while in this example we can see two different threads that are used by this application.

The other mode is Solaris Mode, which can be toggled off by pressing the I button. When operating under this mode, a task’s CPU usage is divided by the total number of CPUs.

5.2. Interaction With the Task Window

We can change the fields and their order by pressing the f button. The field menu opens up and then we can select the fields to be shown, their order, sort by fields, and similar tasks.

One of the most useful ways to leverage top is in Forest View Mode. In this mode, the tasks are ordered like a tree and all child tasks are aligned under their respective parents:

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
    1 root      20   0  225840   7196   4716 S   0.0  0.1   5:46.79 systemd
  283 root      19  -1  148972  37300  36300 S   0.0  0.5   0:23.01  `- systemd-journal
  336 root      20   0   47060   4000   2528 S   0.0  0.0   0:01.10  `- systemd-udevd
  862 systemd+  20   0  146112   1276   1208 S   0.0  0.0   0:00.35  `- systemd-timesyn
  864 systemd+  20   0   71072   4556   3916 S   0.0  0.1   0:12.47  `- systemd-resolve
  867 root      20   0   70728   3732   3448 S   0.0  0.0   0:03.05  `- systemd-logind
  871 root      20   0   38428   2748   2652 S   0.0  0.0   0:00.27  `- cron

We can use the x key to highlight the sorted field. We can use the > and < to change the sorted field to the right or left respectively. Some fields have direct key bindings for their sorting, M for %MEM, N for PID, P for %CPU, T for TIME+.

6. Command-Line Options

We can use top in batch mode by passing the -b flag. When in batch mode, top doesn’t accept any input. In general, this is quite useful for passing the output of top command to some other program or file.

So, to set the number of iterations, we can use -n flag:

$ top -b -n10

On the other hand, to change the refresh rate, we can use the -d flag. Notably, we can use fractional seconds with this flag:

$ top -d2.5

To see all the output fields supported by top, we can use the -O flag:

$ top -O
PID
PPID
UID
USER
... more output omitted

We can use these field names to define the sorting order by passing it after the -o flag. So, if we want to sort the output of top by virtual memory, we can use:

$ top -o VIRT

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
23584 abhishe+  20   0 14.593g 554600  58412 S   2.3  6.9  10:25.55 _Postman
22011 abhishe+  20   0 4142400 277884 141424 S   0.7  3.4  22:00.86 gnome-shell
 1183 gdm       20   0 3664328 114104  72160 S   0.0  1.4   6:33.79 gnome-shell
 2008 abhishe+  20   0 2782760  22520  15096 S   0.0  0.3   0:35.15 copyq

Next, we can use various filters for monitoring tasks on the basis of PIDs, users, and others. To filter tasks by PID, we can pass up to 20 comma-separated PIDs with the -p flag:

$ top -p23584,22011

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
22011 abhishe+ 20 0 4144624 276900 141368 S 6.2 3.4 22:16.92 gnome-shell
23584 abhishe+ 20 0 14.593g 554600 58412 S 0.0 6.9 10:29.91 _Postman

Finally, to filter on the basis of users, we can use the -u flag:

$ top -u root

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
503 root     -51   0       0      0      0 S   6.2  0.0  12:55.09 irq/130-iwlwifi
  1 root      20   0  225840   7196   4716 S   0.0  0.1   5:43.72 systemd

Thus, we can control the output of top even before it starts.

7. Setting Refresh Period

Setting a refresh period for the top command is important as it enables us to continuously monitor the resources the system uses over time. By monitoring the resource usage of the system, we can identify the anomalies in the CPU. Additionally, with a consistent refresh interval, we can effectively allocate resources based on the resource utilization of the processes in the system.

Finally, running the top command without modifying the refresh period can lead to system overhead and high resource consumption. Therefore, by setting a refresh period for the top command, we can avoid unnecessary load and optimize the system’s performance.

Although the top command doesn’t facilitate a built-in option to set the refresh period permanently, we can use the systemd tool to permanently set a refresh period for the top command in Linux. The systemd tool manages services and processes in the system.

To leverage systemd for setting a refresh period for the top command, first, let’s create a systemd service file using any text editor:

$ sudo nano /etc/systemd/system/refresh-top.service

Now, we insert some statements into this new service file:

[Unit]
Description= Top Command with an User-Defined Refresh Interval

[Service]
ExecStart=/usr/bin/top -d 10
Restart=always
RestartSec=20

[Install]
WantedBy=default.target

Let’s discuss the final file content:

  • ExecStart tells the systemd service manager to start the top command with a refresh period of 10 seconds
  • Restart makes systemd monitor and restart the top command automatically in case of an error or termination
  • RestartSec delays a potential restart by 20 seconds

Now, we reload the configuration for the systemd tool to reflect the changes we made using the systemctl command:

$ sudo systemctl daemon-reload

Finally, we enable the new service we created and then manually start the service:

$ sudo systemctl enable refresh-top
$ sudo systemctl start refresh-top

Thus, we’ve successfully set a permanent refresh period for the top command in Linux.

8. Conclusion

In this article, we saw how top is useful for getting data about and monitoring the memory and general resource usage of various processes and threads.

We saw its interactive screen and explored the meaning and use of various fields and columns. Then, we also saw some of its command-line options. Finally, we set a system-wide refresh period for top to avoid unnecessary overhead.