Skip to content

ps aux in Linux Explained: Options, Columns and Sort Keys

Updated 8 min read

Updated: 22 October 2026 · Applies to: ps from procps-ng 4.0.4 on Debian 13, Ubuntu 24.04 and Ubuntu 26.04, tested; AlmaLinux 10 ships the same procps-ng 4.0.4, and procps-ng 3.3.17 on AlmaLinux 9.8 gave the same headers and errors in our checks

ps aux lists every process on a Linux system in the BSD "user-oriented" format: a includes other users' processes, x includes processes without a terminal (services), and u adds the USER, %CPU, %MEM, VSZ, RSS, STAT and START columns. ps -ef is the UNIX (POSIX) way to list the same processes: -e selects every process and -f prints the full format with the parent PID. Use ps aux to see CPU and memory use, and ps -ef to see which process started which.

ps aux                                              # all processes, BSD style, CPU and memory columns
ps -ef                                              # all processes, UNIX style, with parent PID (PPID)
ps -eo pid,user,%cpu,%mem,etime,args --sort=-%cpu   # your own columns, sorted
ps auxww                                            # do not cut long command lines
ps L                                                # every column name that -o accepts

This page is the option and column reference. For a walk-through with top and htop, see How to List and Find Running Processes in Linux (ps, top); for filtering by user, PID, terminal, threads and trees, see ps Command Examples for Linux Process Monitoring. All output below is a lab example from a Debian 13 test container (users alice and deploy), so it shows only a few processes.

BSD, UNIX and GNU options: why ps aux and ps -ef both work

According to the ps manual (procps-ng), ps accepts three kinds of options: UNIX options, which may be grouped and must have a dash (-ef); BSD options, which may be grouped and must not have a dash (aux); and GNU long options with two dashes (--sort). The same letter can mean different things in each style:

  • ps ax and ps -e (or -A): all processes. ps ax also shows the STAT column and the full command line.
  • ps u is the user-oriented format; ps -u alice selects the processes of user alice.
  • ps a shows processes with a terminal for all users; ps -a shows them too, but leaves out session leaders such as your shell.
  • ps axl and ps -el: long format. ps axjf and ps -ejH: process tree.
  • ps o pid,comm and ps -o pid,comm: your own columns. ps k -rss and ps --sort=-rss: sorted.

Do not write ps -aux. The manual says it asks for processes with a terminal plus all processes of a user named "x". procps-ng treats it as ps aux when no such user exists, which is why it usually seems to work. In our test, after we created a user called x, ps -aux printed only a header line:

ps -aux

Output:

    PID TTY          TIME CMD

ps aux output, column by column

$ ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           3  0.0  0.0   4056  3072 ?        Ss   11:08   0:00 bash
alice        102  0.0  0.0   2580  1408 ?        S    11:08   0:00 sleep 1001
deploy       108 13.3  0.0   2580  1408 ?        S    11:08   0:01 sleep 1002
root         112  0.0  0.0   6392  3584 ?        R    11:08   0:00 ps aux
(shortened)
  • USER: the effective user the process runs as.
  • PID: the process ID.
  • %CPU: CPU time used divided by the time the process has been running (ps manual). It is an average over the whole life of the process, not the current load.
  • %MEM: RSS as a percentage of the physical RAM.
  • VSZ: virtual memory size in KiB. It counts all mapped memory, so it is usually much larger than RSS.
  • RSS: resident set size, the physical RAM in use, in KiB. This is the number to watch for memory use.
  • TTY: the terminal; ? (no terminal) is normal for services.
  • STAT: the process state (codes below).
  • START: when the process started: HH:MM if it started today, otherwise the day or the year.
  • TIME: total CPU time used so far.
  • COMMAND: the command with its arguments; names in square brackets are kernel threads.

This matters when you hunt for a busy process. Process 108 used the CPU for a few seconds and then slept; ps kept showing a high value that fell slowly, while top showed the current 0.0:

ps -p 108 -o pid,user,etime,time,%cpu,args

Output:

    PID USER         ELAPSED     TIME %CPU COMMAND
    108 deploy         00:12 00:00:01 13.2 sleep 1002
top -b -n 1 -p 108 | tail -2

Output:

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
    108 deploy    20   0    2580   1408   1408 S   0.0   0.0   0:01.60 sleep
(10 seconds later)
ps -p 108 -o pid,user,etime,time,%cpu,args

Output:

    PID USER         ELAPSED     TIME %CPU COMMAND
    108 deploy         00:22 00:00:01  7.1 sleep 1002

For what is busy right now, use top or see Find Top Running Processes by Highest Memory and CPU Usage in Linux.

ps -ef output

$ ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
root           3       0  0 11:08 ?        00:00:00 bash
alice        102       1  0 11:08 ?        00:00:00 sleep 1001
deploy       108       1  7 11:08 ?        00:00:01 sleep 1002
root         109       3  0 11:08 ?        00:00:00 sleep 1003
(shortened)

UID is the user, PPID the parent process ID (here 109 was started by the bash shell, PID 3), C the same lifetime CPU percentage as a whole number, STIME the start time and CMD the command line. ps -eF adds SZ, RSS and PSR (the CPU it last ran on).

STAT codes

From the ps manual. First letter:

  • R running or runnable (on the run queue); S interruptible sleep (waiting for an event); D uninterruptible sleep (usually I/O); I idle kernel thread.
  • T stopped by a job control signal; t stopped by a debugger; Z zombie (finished, not yet reaped by its parent); X dead (should never be seen).

Extra characters in BSD formats such as ps aux: s session leader, l multi-threaded, + in the foreground process group, < high priority, N low priority, L pages locked in memory. Ss on a service is therefore normal.

Built-in output formats

The header line of each format, from our test:

-ef    UID          PID    PPID  C STIME TTY          TIME CMD
-eF    UID          PID    PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
-ely   S   UID     PID    PPID  C PRI  NI   RSS    SZ WCHAN  TTY          TIME CMD
aux    USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
ax         PID TTY      STAT   TIME COMMAND
axl    F   UID     PID    PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
axv        PID TTY      STAT   TIME  MAJFL   TRS   DRS   RSS %MEM COMMAND

-l or l show priority and nice values (PRI, NI), -j or j process groups and sessions, v memory and page faults. ps --help output lists them all.

Choose your own columns with -o

-o (or BSD o, or --format) takes a comma-separated list of format specifiers. name=HEADER renames a column and a bare = removes the header, so ps -C sleep -o pid= prints only the PIDs, which is handy in scripts. -O adds your columns to the default ones.

ps -o pid,user=OWNER,etime=UPTIME,args -C sleep

Output:

    PID OWNER         UPTIME COMMAND
      2 root           00:37 sleep 7200
    102 alice          00:22 sleep 1001
    108 deploy         00:22 sleep 1002
    109 root           00:22 sleep 1003
ps -p 108 -o pid,etime,etimes,rss,vsz

Output:

    PID     ELAPSED ELAPSED   RSS    VSZ
    108       00:22      22  1408   2580

Useful specifiers (meanings from the ps manual):

  • IDs and users: pid, ppid (parent), pgid, sid, user (effective), ruser (real), uid, group.
  • State and scheduling: stat, ni (nice, 19 nicest to -20), pri, psr (last CPU), nlwp (threads), wchan (kernel function it sleeps in).
  • CPU and memory: %cpu, %mem, rss, vsz, sz.
  • Time: etime ([[DD-]hh:]mm:ss running), etimes (seconds running), lstart (full start date), start, stime, time (CPU time).
  • Command: comm (program name only), args or cmd (full command line), tty, cgroup, label (SELinux).

ps L prints every specifier with its header (190 lines on procps-ng 4.0.4, 175 on 3.3.17). A wrong name stops ps with error: unknown user-defined format specifier "bogus". Add :WIDTH to widen a column, for example wchan:20.

Sort with --sort (or k)

The syntax is --sort=[+|-]key[,[+|-]key...], where key is a format specifier name: - sorts from high to low, + (the default) from low to high. The BSD form is k. The sort key does not need to be one of the columns you print.

ps -eo pid,user,rss,args --sort=-rss | head -4

Output:

    PID USER       RSS COMMAND
    122 root      3584 ps -eo pid,user,rss,args --sort=-rss
      3 root      3072 bash
      2 root      1408 sleep 7200

Several keys are separated by commas: ps -eo pid,user,args --sort=user,-pid listed alice, deploy and then root, with each user's newest PID first.

Common keys: -%cpu, -%mem, -rss (most RAM first), etime (newest first), -etime (oldest first), user, pid. An unknown key gives error: unknown sort specifier. ps aux k -rss is the BSD spelling of ps aux --sort=-rss.

Long command lines are cut on screen

When ps writes to a terminal, it cuts each line at the terminal width. Add ww (BSD) or -ww (UNIX) for unlimited width; a single w only widens it. On an 80-column terminal in our test:

ps u -p 147

Output:

USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
alice        147  0.0  0.0   2580  1280 ?        S    11:08   0:00 sleep 1004 0.

ps uww -p 147 printed the whole command line. The manual says the width is undefined when the output goes into a pipe or a file; in our tests ps aux | grep printed full lines, and so did COLUMNS=200 ps u.

Other switches worth knowing

Official documentation: ps manual (procps-ng).

Related services

KVM VPS hosting

NVMe SSD and full root access, with Free Basic Managed Support.

Unmanaged dedicated servers

full root access and free IPMI KVM, with Free Basic Managed Support.

Linux server management

hardening, patching, monitoring and automation for Ubuntu, Debian, RHEL and AlmaLinux.

Was this answer helpful?

Still stuck? Open a ticket