How to get current CPU and RAM usage in Python?
Solution 1
The psutil library gives you information about CPU, RAM, etc., on a variety of platforms:
psutil is a module providing an interface for retrieving information on running processes and system utilization (CPU, memory) in a portable way by using Python, implementing many functionalities offered by tools like ps, top and Windows task manager.
It currently supports Linux, Windows, OSX, Sun Solaris, FreeBSD, OpenBSD and NetBSD, both 32-bit and 64-bit architectures, with Python versions from 2.6 to 3.5 (users of Python 2.4 and 2.5 may use 2.1.3 version).
Some examples:
#!/usr/bin/env python
import psutil
# gives a single float value
psutil.cpu_percent()
# gives an object with many fields
psutil.virtual_memory()
# you can convert that object to a dictionary
dict(psutil.virtual_memory()._asdict())
# you can have the percentage of used RAM
psutil.virtual_memory().percent
79.2
# you can calculate percentage of available memory
psutil.virtual_memory().available * 100 / psutil.virtual_memory().total
20.8
Here's other documentation that provides more concepts and interest concepts:
Solution 2
Use the psutil library. On Ubuntu 18.04, pip installed 5.5.0 (latest version) as of 1-30-2019. Older versions may behave somewhat differently. You can check your version of psutil by doing this in Python:
from __future__ import print_function # for Python2
import psutil
print(psutil.__version__)
To get some memory and CPU stats:
from __future__ import print_function
import psutil
print(psutil.cpu_percent())
print(psutil.virtual_memory()) # physical memory usage
print('memory % used:', psutil.virtual_memory()[2])
The virtual_memory
(tuple) will have the percent memory used system-wide. This seemed to be overestimated by a few percent for me on Ubuntu 18.04.
You can also get the memory used by the current Python instance:
import os
import psutil
pid = os.getpid()
python_process = psutil.Process(pid)
memoryUse = python_process.memory_info()[0]/2.**30 # memory use in GB...I think
print('memory use:', memoryUse)
which gives the current memory use of your Python script.
There are some more in-depth examples on the pypi page for psutil.
Solution 3
Only for Linux: One-liner for the RAM usage with only stdlib dependency:
import os
tot_m, used_m, free_m = map(int, os.popen('free -t -m').readlines()[-1].split()[1:])
Solution 4
One can get real time CPU and RAM monitoring by combining tqdm
and psutil
. It may be handy when running heavy computations / processing.
It also works in Jupyter without any code changes:
from tqdm import tqdm
from time import sleep
import psutil
with tqdm(total=100, desc='cpu%', position=1) as cpubar, tqdm(total=100, desc='ram%', position=0) as rambar:
while True:
rambar.n=psutil.virtual_memory().percent
cpubar.n=psutil.cpu_percent()
rambar.refresh()
cpubar.refresh()
sleep(0.5)
It's convenient to put those progress bars in separate process using multiprocessing library.
This code snippet is also available as a gist.
Solution 5
Below codes, without external libraries worked for me. I tested at Python 2.7.9
CPU Usage
import os
CPU_Pct=str(round(float(os.popen('''grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage }' ''').readline()),2))
print("CPU Usage = " + CPU_Pct) # print results
And Ram Usage, Total, Used and Free
import os
mem=str(os.popen('free -t -m').readlines())
"""
Get a whole line of memory output, it will be something like below
[' total used free shared buffers cached\n',
'Mem: 925 591 334 14 30 355\n',
'-/+ buffers/cache: 205 719\n',
'Swap: 99 0 99\n',
'Total: 1025 591 434\n']
So, we need total memory, usage and free memory.
We should find the index of capital T which is unique at this string
"""
T_ind=mem.index('T')
"""
Than, we can recreate the string with this information. After T we have,
"Total: " which has 14 characters, so we can start from index of T +14
and last 4 characters are also not necessary.
We can create a new sub-string using this information
"""
mem_G=mem[T_ind+14:-4]
"""
The result will be like
1025 603 422
we need to find first index of the first space, and we can start our substring
from from 0 to this index number, this will give us the string of total memory
"""
S1_ind=mem_G.index(' ')
mem_T=mem_G[0:S1_ind]
"""
Similarly we will create a new sub-string, which will start at the second value.
The resulting string will be like
603 422
Again, we should find the index of first space and than the
take the Used Memory and Free memory.
"""
mem_G1=mem_G[S1_ind+8:]
S2_ind=mem_G1.index(' ')
mem_U=mem_G1[0:S2_ind]
mem_F=mem_G1[S2_ind+8:]
print 'Summary = ' + mem_G
print 'Total Memory = ' + mem_T +' MB'
print 'Used Memory = ' + mem_U +' MB'
print 'Free Memory = ' + mem_F +' MB'
lpfavreau
Updated on February 13, 2022Comments
-
lpfavreau about 2 years
What's your preferred way of getting the current system status (current CPU, RAM, free disk space, etc.) in Python? Bonus points for unix and Windows platforms.
There seems to be a few possible ways of extracting that from my search:
-
Using a library such as PSI (that currently seems not actively developed and not supported on multiple platforms) or something like pystatgrab (again no activity since 2007 it seems and no support for Windows).
-
Using platform specific code such as using a
os.popen("ps")
or similar for the *nix systems andMEMORYSTATUS
inctypes.windll.kernel32
(see this recipe on ActiveState) for the Windows platform. One could put a Python class together with all those code snippets.
It's not that those methods are bad but is there already a well-supported, multi-platform way of doing the same thing?
-
-
user1066101 over 15 years@J.F.Sebastian: Which Windows? I get a 'df' is not recognized... error message from Windows XP Pro. What am I missing?
-
phobie over 11 yearsUse GlobalMemoryStatusEx instead of GlobalMemoryStatus because the old one can return bad values.
-
phobie over 11 yearsYou should avoid
from x import *
statements! They clutter the main-namespace and overwrite other functions and variables. -
hobs almost 11 yearsWorked for me on OSX:
$ pip install psutil
;>>> import psutil; psutil.cpu_percent()
and>>> psutil.virtual_memory()
which returns a nice vmem object:vmem(total=8589934592L, available=4073336832L, percent=52.6, used=5022085120L, free=3560255488L, active=2817949696L, inactive=513081344L, wired=1691054080L)
-
BigBrownBear00 about 9 yearsHow would one do this without the psutil library?
-
jfs about 9 yearsyou can install new programs on Windows too.
-
Austin A almost 9 years@user1054424 There is a builtin library in python called resource. However, it seems the most you can do with it is grab the memory that a single python process is using and/or it's child processes. It also doesn't seem very accurate. A quick test showed resource being off by about 2MB from my mac's utility tool.
-
Mehulkumar over 7 years@BigBrownBear00 just check source of psutil ;)
-
Reinderien over 5 yearsDon't you think the
grep
andawk
would be better taken care of by string processing in Python? -
Jay over 5 yearsPersonally not familiar with awk, made an awkless version of the cpu usage snippet below. Very handy, thanks!
-
Captain Lepton over 5 yearsIt's disingenuous to say that this code does not use external libraries. In fact, these have a hard dependency on the availability of grep, awk and free. This makes the code above non-portable. The OP stated "Bonus points for *nix and Windows platforms."
-
riverfall over 5 yearsyou have a typo in the string "psutil.virtual_memory()`"
-
AiRiFiEd about 5 years@Jon Cage hi Jon, may I check with you on the difference between free and available memory? I am planning to use psutil.virtual_memory() to determine how much data i can load into memory for analysis. Thanks for your help!
-
Jon Cage about 5 years@AiRiFiEd - reviversoft.com/blog/2013/10/…
-
AiRiFiEd about 5 years@Jon Cage thank you! tried googling but didnt get anything as concise - my understanding would then be to use free memory for my purpose.
-
Paras Korat about 5 yearsadd some more description
-
iipr over 4 yearsVery useful! To obtain it directly in human readable units:
os.popen('free -th').readlines()[-1].split()[1:]
. Note that this line returns a list of strings. -
Martin Thoma almost 4 yearsThe
python:3.8-slim-buster
does not havefree
-
Martin Thoma almost 4 yearsSeems not to work as expected: stackoverflow.com/q/61498709/562769
-
Mr. Duhart over 3 yearsTake a look here, @MartinThoma.
-
Julio CamPlaz almost 3 yearspsutil can do this, and several statement combinations with the library os
-
MiloMinderbinder almost 3 yearsused_m, free_m don't add up to tot_m. The results also don't match with htop. What am I misunderstanding?
-
MrR almost 3 yearsplease don't call variables
py
-
wordsforthewise almost 3 yearsI know it's not best practice now, but py isn't a keyword or anything like that. Is there a reason beyond not being a descriptive variable name you are saying don't use
py
? -
MrR almost 3 yearsIt's universally used in so many other contexts to indicate "something that pertains to python" e.g. redis-py. I wouldn't use the two-letter py to indicate the current process.
-
tripleee over 2 yearsThis is not a good examble of how to use the
subprocess
library. Like its documentation says, you should avoid barePopen
in favor of one of the higher-level functionssubprocess.check_output
orsubprocess.run
. It's unclear what./ps_mem
is here. -
tripleee over 2 yearsThis is obviously specific to Linux.
-
webelo over 2 yearsImportant to underline that this doesn't answer the original question (and is likely not what people are searching for). It was good to learn about this package, though.
-
Thor over 2 yearsI liked the idea of the resource library to watch my python code, so I tried the getrusuage() function on a debian box. ru_maxrss always returned the same number using ..._SELF, _CHILDREN, or _THREAD options, even though I was starting threads and subprocesses. The option _BOTH errored. Other params (ixrss, idrss, isrss) all returned zeros.
-
alper about 2 years
psutil.cpu_percent()
returns 0 is it normal? -
davidvandebunte about 2 yearsRemove unused
import os
-
bumpbump about 2 yearsI want to make a comment that this is quite expensive operation, so don't try to do this in some tight loop as a condition to see if you should do something in the program