Performance

This page describes how to use psutil efficiently.

Use oneshot() when reading multiple process attributes

If you’re dealing with a single Process instance and need to retrieve multiple process attributes, use Process.oneshot(). Each method call issues a separate system call, but the OS often returns multiple attributes at once, which Process.oneshot() caches for subsequent calls.

Slow:

import psutil

p = psutil.Process()
p.name()           # syscall
p.cpu_times()      # syscall
p.memory_info()    # syscall
p.status()         # syscall

Fast:

import psutil

p = psutil.Process()
with p.oneshot():
    p.name()         # one syscall, result cached
    p.cpu_times()    # from cache
    p.memory_info()  # from cache
    p.status()       # from cache

The speed improvement depends on the platform and on how many attributes you read. On Linux the gain is typically around 1.5x–2x; on Windows it can be much higher. As a rule of thumb: if you read more than one attribute from the same process, use Process.oneshot().

Use process_iter() with an attrs list

If you iterate over multiple PIDs, always use process_iter(). It accepts an attrs argument that pre-fetches only the requested attributes in a single pass, minimizing system calls by fetching multiple attributes at once. This is faster than calling individual methods in a loop.

Slow:

Fast:

import psutil

for p in psutil.process_iter(["name", "status"]):
    print(p.pid, p.name(), p.status())  # return cached values, never raise

process_iter(attrs=...) is effectively equivalent to using Process.oneshot() on each process. Using process_iter() also saves you from race conditions (e.g. if a process disappears while iterating), since NoSuchProcess and AccessDenied exceptions are handled internally. A typical use case is to fetch all process attrs except the slow ones (see Measuring APIs speed table below):

import psutil

for p in psutil.process_iter(psutil.Process.attrs - {"memory_footprint", "memory_maps"}):
    ...

Methods sped up by oneshot()

Here’s a list of method groups for each platform which can benefit from Process.oneshot(). Methods in each group (in the same comma-separated list) share the same underlying system call.

The speedup represents the estimated gain when all listed methods are called together (best case), as measured by scripts/internal/bench_oneshot.py.

Additionally, some methods are computed from other methods, so on every platform Process.oneshot() also speeds up cpu_percent() (from cpu_times()), memory_percent() (from memory_info()), parent() and parents() (from ppid()) and, on POSIX, username() (from uids()).

Linux

Speedup: +1.7×

Windows

Some of these first try a faster dedicated call, and only use the shared one if it raises AccessDenied. The second figure is for such processes.

Speedup: +1.8× / +6.5×

macOS

Speedup: +1.6×

BSD

Speedup: +2.7×

Measuring oneshot() speedup

scripts/internal/bench_oneshot.py measures Process.oneshot() speedup. It also shows which APIs share the same internal kernel routines. E.g. on Linux:

$ python3 scripts/internal/bench_oneshot.py --times 10000
17 methods pre-fetched by oneshot() on platform 'linux' (10,000 times, psutil 8.0.0):

  cpu_num
  cpu_percent
  cpu_times
  gids
  memory_extras
  memory_info
  memory_percent
  name
  num_ctx_switches
  num_threads
  page_faults
  parent
  ppid
  status
  terminal
  uids
  username

regular:  2.600 secs
oneshot:  1.499 secs
speedup:  +1.73x

Measuring APIs speed

scripts/internal/print_api_speed.py shows the relative cost of each API call. This helps you understand which operations are more expensive. E.g. on Linux:

$ python3 scripts/internal/print_api_speed.py
SYSTEM APIS                NUM CALLS      SECONDS
-------------------------------------------------
getloadavg                       300      0.00013
heap_info                        300      0.00028
heap_trim                        300      0.00039
cpu_count                        300      0.00061
disk_usage                       300      0.00066
pid_exists                       300      0.00235
users                            300      0.00455
net_io_counters                  300      0.00550
cpu_times                        300      0.00667
boot_time                        300      0.00700
cpu_percent                      300      0.00766
net_if_stats                     300      0.00783
virtual_memory                   300      0.00834
cpu_times_percent                300      0.00885
net_if_addrs                     300      0.01157
cpu_stats                        300      0.01208
swap_memory                      300      0.01558
disk_partitions                  300      0.01664
disk_io_counters                 300      0.02204
sensors_battery                  300      0.02995
pids                             300      0.05295
cpu_count (cores)                300      0.06943
process_iter (all)               300      0.08486
cpu_freq                         300      0.18987
sensors_fans                     300      0.74027
net_connections                  161      2.00690
sensors_temperatures             100      2.00742

PROCESS APIS               NUM CALLS      SECONDS
-------------------------------------------------
exe                              300      0.00017
create_time                      300      0.00020
nice                             300      0.00025
ionice                           300      0.00041
cwd                              300      0.00052
cpu_affinity                     300      0.00059
num_fds                          300      0.00097
memory_info                      300      0.00201
cmdline                          300      0.00222
io_counters                      300      0.00226
cpu_num                          300      0.00242
status                           300      0.00242
terminal                         300      0.00243
name                             300      0.00249
page_faults                      300      0.00258
memory_percent                   300      0.00259
cpu_times                        300      0.00272
threads                          300      0.00278
num_threads                      300      0.00278
gids                             300      0.00296
num_ctx_switches                 300      0.00299
uids                             300      0.00311
cpu_percent                      300      0.00346
net_connections                  300      0.00373
open_files                       300      0.00378
memory_extras                    300      0.00398
username                         300      0.00500
ppid                             300      0.00556
environ                          300      0.01176
memory_footprint                 300      0.02218
memory_maps                      300      0.27158