How to get current CPU and RAM usage in Python?

556,437

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.__versi‌​on__)

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.

cli cpu and ram usage progress bars

It also works in Jupyter without any code changes:

Jupyter cpu and ram usage progress bars

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'
Share:
556,437
lpfavreau
Author by

lpfavreau

Updated on February 13, 2022

Comments

  • lpfavreau
    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:

    1. 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).

    2. Using platform specific code such as using a os.popen("ps") or similar for the *nix systems and MEMORYSTATUS in ctypes.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
    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
    phobie over 11 years
    Use GlobalMemoryStatusEx instead of GlobalMemoryStatus because the old one can return bad values.
  • phobie
    phobie over 11 years
    You should avoid from x import * statements! They clutter the main-namespace and overwrite other functions and variables.
  • hobs
    hobs almost 11 years
    Worked 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
    BigBrownBear00 about 9 years
    How would one do this without the psutil library?
  • jfs
    jfs about 9 years
    you can install new programs on Windows too.
  • Austin A
    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
    Mehulkumar over 7 years
    @BigBrownBear00 just check source of psutil ;)
  • Reinderien
    Reinderien over 5 years
    Don't you think the grep and awk would be better taken care of by string processing in Python?
  • Jay
    Jay over 5 years
    Personally not familiar with awk, made an awkless version of the cpu usage snippet below. Very handy, thanks!
  • Captain Lepton
    Captain Lepton over 5 years
    It'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
    riverfall over 5 years
    you have a typo in the string "psutil.virtual_memory()`"
  • AiRiFiEd
    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
    Jon Cage about 5 years
  • AiRiFiEd
    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
    Paras Korat about 5 years
    add some more description
  • iipr
    iipr over 4 years
    Very 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
    Martin Thoma almost 4 years
    The python:3.8-slim-buster does not have free
  • Martin Thoma
    Martin Thoma almost 4 years
    Seems not to work as expected: stackoverflow.com/q/61498709/562769
  • Mr. Duhart
    Mr. Duhart over 3 years
    Take a look here, @MartinThoma.
  • Julio CamPlaz
    Julio CamPlaz almost 3 years
    psutil can do this, and several statement combinations with the library os
  • MiloMinderbinder
    MiloMinderbinder almost 3 years
    used_m, free_m don't add up to tot_m. The results also don't match with htop. What am I misunderstanding?
  • MrR
    MrR almost 3 years
    please don't call variables py
  • wordsforthewise
    wordsforthewise almost 3 years
    I 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
    MrR almost 3 years
    It'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
    tripleee over 2 years
    This is not a good examble of how to use the subprocess library. Like its documentation says, you should avoid bare Popen in favor of one of the higher-level functions subprocess.check_output or subprocess.run. It's unclear what ./ps_mem is here.
  • tripleee
    tripleee over 2 years
    This is obviously specific to Linux.
  • webelo
    webelo over 2 years
    Important 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
    Thor over 2 years
    I 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
    alper about 2 years
    psutil.cpu_percent() returns 0 is it normal?
  • davidvandebunte
    davidvandebunte about 2 years
    Remove unused import os
  • bumpbump
    bumpbump about 2 years
    I 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