Finding the exact process that is consuming CPU time or resident memory is the quickest path from “the server is slow” to a concrete fix on Linux systems, especially when load spikes, fan noise, or sudden OOM kills appear.

Process resource numbers come from the kernel’s procfs (/proc/), which tools like ps and top read to summarize per-process CPU and memory consumption. A ps listing provides a sortable snapshot, while top adds a sampled view that updates on an interval to expose short-lived spikes.

Percentages and sizes need the right interpretation: %CPU can vary based on sampling window and CPU count, %MEM is relative to total RAM, and a large VIRT value does not necessarily mean large physical memory use. When containers or cgroups are involved, limits can also make percentages look surprising compared to “host-wide” totals.

Steps to check process CPU and memory usage with ps and top in Linux:

  1. List the top CPU consumers with ps.
    $ ps -eo pid,comm,%cpu,%mem --sort=-%cpu | head -n 8
        PID COMMAND         %CPU %MEM
       3782 python3          2.8  0.4
          1 systemd          0.3  0.3
       2249 fwupd            0.2  1.0
        686 dbus-daemon      0.0  0.1
       3179 systemd          0.0  0.2
       3718 sshd             0.0  0.2
         11 kworker/u4:0-fl  0.0  0.0
  2. List the top resident-memory consumers with ps.
    $ ps -eo pid,comm,rss,%mem --sort=-rss | head -n 8
        PID COMMAND           RSS %MEM
       2249 fwupd           41916  1.0
        364 multipathd      26240  0.6
        850 unattended-upgr 21888  0.5
       1593 packagekitd     19200  0.4
       3782 python3         18816  0.4
        311 systemd-journal 17368  0.4
          1 systemd         12660  0.3

    RSS is the resident set size shown in KiB by default.

  3. Inspect the full command line and runtime for a heavy PID.
    $ ps -p 3782 -o pid,user,etime,pcpu,pmem,rss,args
        PID USER         ELAPSED %CPU %MEM   RSS COMMAND
       3782 root           00:01  2.7  0.4 18816 python3 -m http.server 9000 --bind 127.0.0.1
  4. Capture a one-time sampled snapshot using top.
    $ top -b -n 1 | head -n 12
    top - 12:15:51 up 6 min,  2 users,  load average: 0.18, 0.10, 0.04
    Tasks: 123 total,   1 running, 121 sleeping,   0 stopped,   1 zombie
    %Cpu(s):  0.0 us,  4.2 sy,  0.0 ni, 95.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st 
    MiB Mem :   3901.5 total,   2923.8 free,    326.2 used,    809.2 buff/cache     
    MiB Swap:   2048.0 total,   2048.0 free,      0.0 used.   3575.3 avail Mem 
    
        PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
       3791 user      20   0   11752   4992   3072 R   9.1   0.1   0:00.03 top
          1 root      20   0   22416  12660   8564 S   0.0   0.3   0:01.43 systemd
          2 root      20   0       0      0      0 S   0.0   0.0   0:00.00 kthreadd
          3 root      20   0       0      0      0 S   0.0   0.0   0:00.00 pool_wo+
          4 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 kworker+

    Use interactive top for live sorting: P sorts by %CPU and M sorts by %MEM.