Retrieve CPU usage and memory usage of a single process on Linux?
I want to get the CPU and memory usage of a single process on Linux — I know the PID. Hopefully, I can get it every second and write it to a CSV using the ‘watch’ command. What command can I use to get this info from the Linux command-line?
22 Answers 22
(You can leave off «cmd» but that might be helpful in debugging).
Note that this gives average CPU usage of the process over the time it has been running.
The assumption would be that if you care about a single processes’ memory usage enough to monitor it like this, it’s using a significant amount of memory so that the extra couple-of-megabytes due to shared mappings isn’t an issue.
Keep in mind that %cpu «is the CPU time used divided by the time the process has been running (cputime/realtime ratio), expressed as a percentage» (see manpage of ps ). This is not the real just in time CPU usage. It can also be very different from what top shows, for instance.
as said from Xebeche just above, ps -e -o pcpu,args will show the cpu average over the lifetime of the process, which is obviously not what you want if it is a long running process
This auto-refreshes the CPU usage so it’s good for monitoring.
@MatthiasBraun should be top -p $(pgrep -d’,’ process_name) please see stackoverflow.com/a/8710740/2402577
ps command (should not use):
Use top to get CPU usage in real time(current short interval):
top -b -n 2 -d 0.2 -p 6962 | tail -1 | awk »
- -b : Batch-mode
- -n 2 : Number-of-iterations, use 2 because: When you first run it, it has no previous sample to compare to, so these initial values are the percentages since boot.
- -d 0.2 : Delay-time(in second, here is 200ms)
- -p 6962 : Monitor-PIDs
- tail -1 : the last row
- awk » : the 9-th column(the cpu usage number)
This is the most accurate answer to get the current CPU usage, not an average over the lifetime of the process.
You can get the results by the name of the process using
the -C option allows you to use process name without knowing it’s pid.
e.g. to monitor these two process IDs (12345 and 11223) every 5 seconds use
$ pidstat -h -r -u -v -p 12345,11223 5
pidstat also gives a nice average. just a shame i have not found a more elegant way of pidstat -u 1 10 | grep ^Average | sort -r -n -b -k 8,8
Launch a program and monitor it
This form is useful if you want to benchmark an executable easily:
topp() ( if [ -n "$O" ]; then $* & else $* &>/dev/null & fi pid="$!" trap "kill $pid" SIGINT o='%cpu,%mem,vsz,rss' printf '%s\n' "$o" i=0 while s="$(ps --no-headers -o "$o" -p "$pid")"; do printf "$i $s\n" i=$(($i + 1)) sleep "$" done )
%cpu,%mem,vsz 0 0.0 0.0 177584 1 0.0 0.1 588024 2 0.0 0.1 607084 3 0.0 0.2 637248 4 0.0 0.2 641692 5 68.0 0.2 637904 6 80.0 0.2 642832
where vsz is the total memory usage in KiB, e.g. the above had about 600MiB usage.
If your program finishes, the loop stops and we exit topp .
Alternatively, if you git Ctrl + C, the program also stops due to the trap : How do I kill background processes / jobs when my shell script exits?
- T=0.5 topp ./myprog : change poll interval
- O=1 topp ./myprog : don’t hide program stdout/stderr. This can be useful to help correlate at which point memory usage bursts with stdout.
ps vs top on instantaneous CPU% usage
Note that the CPU usage given by ps above is not «instantaneous» (i.e. over the last N seconds), but rather the average over the processes’ entire lifetime as mentioned at: https://unix.stackexchange.com/questions/58539/top-and-ps-not-showing-the-same-cpu-result ps memory measures should be fine however.
That thread as well as: How can I determine the current CPU utilization from the shell? suggest that the Linux kernel does not store any more intermediate usage statistics, so the only way to do that would be to poll and calculate for the previous period, which is what top does.
We could therefore use top -n1 instead of ps if we wanted that:
toppp() ( $* &>/dev/null & pid="$!" trap exit SIGINT i=1 top -b n1 -d "$" -n1 -p "$pid" while true; do top -b n1 -d "$" -n1 -p "$pid" | tail -1; printf "$i "; i=$(($i + 1)); done )
as mentioned e.g. at: https://stackoverflow.com/a/62421136/895245 which produces output of type:
top - 17:36:59 up 9:25, 12 users, load average: 0.32, 1.75, 2.21 Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie %Cpu(s): 13.4 us, 2.5 sy, 0.0 ni, 84.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st MiB Mem : 31893.7 total, 13904.3 free, 15139.8 used, 2849.7 buff/cache MiB Swap: 0.0 total, 0.0 free, 0.0 used. 16005.5 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 706287 ciro 20 0 590436 40352 20568 R 106.7 0.1 0:00.16 node 706287 ciro 20 0 607060 57172 21340 R 126.7 0.2 0:00.35 node 1 706287 ciro 20 0 642008 80276 21812 R 113.3 0.2 0:00.52 node 2 706287 ciro 20 0 641676 93108 21812 R 113.3 0.3 0:00.70 node 3 706287 ciro 20 0 647892 99956 21812 R 106.7 0.3 0:00.87 node 4 706287 ciro 20 0 655980 109564 21812 R 140.0 0.3 0:01.09 node
My only problems with this is that top is not as nice for interactive usage:
- Ctrl + C does not exit the above command, not sure why trap exit is not working as it does with ps . I have to kill the command Ctrl + \ , and then that does not kill the process itself which continues to run on the background, which means that if it is an infinite loop like a server, I have to ps aux and then kill it.
- the not exit automatically when the benchmarked program exits
Maybe someone more shell savvy than me can find a solution for those.
ps memory measurements should be the same as top however if you’re just after memory.
How to get percentage of processor use with bash?
I wonder how do I get the percentage of my processor usage from 0% to 100%? to know how many percent’m using my processor preferably in bash or other methods provided that percentage. I have this script that I found on google however it is very much imprecisso I tried to make more improvements could not, does anyone know any method to get the percentage of CPU utilization in% 0-100 my script
NUMCPUS=`grep ^proc /proc/cpuinfo | wc -l`; FIRST=`cat /proc/stat | awk '/^cpu / '`; sleep 1; SECOND=`cat /proc/stat | awk '/^cpu / '`; USED=`echo 2 k 100 $SECOND $FIRST - $NUMCPUS / - p | dc`; echo $% CPU Usage
5 Answers 5
Processor use or utilization is a measurement over time. One way to measure utilization in % is by computation over two successive reads of /proc/stat . A simple common bash script to compute the percentage is:
#!/bin/bash # Read /proc/stat file (for first datapoint) read cpu user nice system idle iowait irq softirq steal guest< /proc/stat # compute active and total utilizations cpu_active_prev=$((user+system+nice+softirq+steal)) cpu_total_prev=$((user+system+nice+softirq+steal+idle+iowait)) usleep 50000 # Read /proc/stat file (for second datapoint) read cpu user nice system idle iowait irq softirq steal guest< /proc/stat # compute active and total utilizations cpu_active_cur=$((user+system+nice+softirq+steal)) cpu_total_cur=$((user+system+nice+softirq+steal+idle+iowait)) # compute CPU utilization (%) cpu_util=$((100*( cpu_active_cur-cpu_active_prev ) / (cpu_total_cur-cpu_total_prev) )) printf " Current CPU Utilization : %s\n" "$cpu_util" exit 0
$ bash procstat-cpu.sh Current CPU Utilization : 10
output over 5 iterations:
$ ( declare -i cnt=0; while [ "$cnt" -lt 5 ]; do bash procstat-cpu.sh; ((cnt++)); done ) Current CPU Utilization : 20 Current CPU Utilization : 18 Current CPU Utilization : 18 Current CPU Utilization : 18 Current CPU Utilization : 18
@DavidC.Rankin That is quite the read! I think your formulae is for CPU utilization over .05 second (50,000 microseconds). My conky display updates per CPU percentage every second . If it used your formulae then 95% of utilization would me missing? Note sure on this, but wouldn't it be easier to calculate idle % and if it were say 80% then one could infer CPU utilization was 20% including system, user, IRQs, etc? Anyway thanks for sharing 🙂
Cpu(s): 15.4%us, 5.3%sy, 0.0%ni, 78.6%id, 0.5%wa, 0.0%hi, 0.1%si, 0.0%st
You can pull any CPU field with the following will take the user CPU (us)
top -bn1 | sed -n '/Cpu/p' | awk '' | sed 's/. //'
If you want another field like system CPU (sy) you can change the awk field from $2,
top -bn1 | sed -n '/Cpu/p' | awk '' | sed 's/. //'
us: user CPU used by user processes sy: system CPU used by system/kernel processes ni: nice CPU used by processes that were reniced id: idle CPU not used wa: io wait Essentially idle CPU waiting on IO devices hi: hardware irq CPU used to service hardware IRQs si: software irq CPU used to service soft IRQs st: steal time CPU time which the hypervisor dedicated (or ‘stole’) for other guests in the system.
To get usage percent total since bringing the system up:
To get the usage percentage over the last second:
awk -v a="$(awk '/cpu /' /proc/stat; sleep 1)" '/cpu /' /proc/stat
Explanation
From man 5 proc , the meaning of the first four numbers on the cpu line in /proc/stat is given by:
cpu 3357 0 4313 1362393
The amount of time, measured in units of USER_HZ (1/100ths of a second on most architectures, use sysconf(_SC_CLK_TCK) to obtain the right value), that the system spent in user mode, user mode with low priority (nice), system mode, and the idle task, respectively. The last value should be USER_HZ times the second entry in the uptime pseudo-file.
The get the CPU usage, we add the user and system times and divide by the total of user, system, and idle time.
Let's look again at the calculation for total CPU usage since system up:
By requiring that the line match cpu , we get system totals. The second column is user time, the fourth is system time, and the fifth is idle time. The ratio is multiplied by 100 to get a percentage.
Now, let's consider the recent CPU usage:
awk -v a="$(awk '/cpu /' /proc/stat; sleep 1)" '/cpu /' /proc/stat
This reads /proc/cpu twice, a second apart. The first time, the CPU user + system, and user+system+idle times are saved in the variable a . sleep is called to delay for a second. Then, /proc/cpu is read a second time. Tne old user+system total is subtracted from the new total and divided by the change in the total of all times. The result is multiplied by 100 to convert it to percent and printed.
Thank good it's really what I wanted to put thought means inaccurate, you explain the calculations that helped me a lot! thank you friend!
Using vmstat the command is short, moderately accurate and takes one second :
Very simple script that considers only System, Idle and User.
The benefit over the other answers is that it requires no utilities, not even top, and also displays fractions, which the current top answer does not.
#!/bin/bash read u1 s1 i1 ' ) sleep 1 read u2 s2 i2 ' ) u=$(echo "scale=4;$u2-$u1" | bc) s=$(echo "scale=4;$s2-$s1" | bc) i=$(echo "scale=4;$i2-$i1" | bc) cpu=$(echo "scale=4;($u+$s)*100/($u+$s+$i)" | bc) echo $cpu
Brief description - we pull data from /proc/stat from the line that starts with 'cpu'. We then get parse out the second token which is user time, the fourth token which is system time and fifth token which is idle time.
At this point, you may be tempted to just do the math, but all that will give you is the utilization since boot time. We need one more data point.
We sleep 1 second and we pull the data from /proc/stat again. Now we get the difference between the first pull and the second pull. This is the CPU utilization for that 1 second while we slept.
We get the difference for each of the variables, and then do the math on the difference. The strange 'scale=4' in front of each calculation is to force a float answer with 4 digit precision.