skip to content

ps, ss & netstat β€” Processes & Sockets

Inspect running processes (ps), list network connections and listening ports (ss / netstat). Covers output formats, filtering, process trees, and socket state analysis.

6 min read 13 snippets 2d ago intermediate

ps, ss & netstat β€” Processes & Sockets#


ps β€” Process Status#

Syntax styles#

ps accepts both BSD (ps aux) and POSIX/Unix (ps -ef) style options β€” don’t mix them.

Most common invocations#

ps aux               # all processes, user-friendly (BSD)
ps -ef               # all processes, full format (POSIX)
ps -eF               # POSIX + extra columns
ps -ely              # POSIX + long format (no truncation)
ps axjf              # BSD + forest (process tree)
ps -ejH              # POSIX + hierarchical tree

Column reference (BSD aux)#

ColumnMeaning
USERProcess owner
PIDProcess ID
%CPUCPU usage %
%MEMMemory usage %
VSZVirtual memory size (KB)
RSSResident (physical) memory (KB)
TTYControlling terminal
STATProcess state
STARTStart time
TIMECumulative CPU time
COMMANDCommand + arguments

Process states (STAT)#

CodeMeaning
RRunning or runnable
SSleeping (interruptible)
DUninterruptible sleep (I/O)
TStopped (signal or debugger)
ZZombie (finished, not reaped)
<High priority
NLow priority
LLocked pages in memory
sSession leader
lMulti-threaded
+Foreground process group

Filtering and searching#

ps aux | grep nginx                  # find by name
ps aux | grep -v grep | grep nginx   # exclude grep itself
ps -C nginx                          # by command name (POSIX)
ps -p 1234                           # by PID
ps -p 1234,5678                      # multiple PIDs
ps -u alice                          # by user
ps --ppid 1234                       # children of PID

# Find PID of a program
pgrep nginx                          # print matching PIDs
pgrep -l nginx                       # with process names
pgrep -a nginx                       # with full command
pgrep -u root nginx                  # by user + name

Custom output format#

ps -eo pid,ppid,user,%cpu,%mem,vsz,rss,stat,comm
ps -eo pid,user,comm --sort=-%cpu | head -15     # top CPU consumers
ps -eo pid,user,comm --sort=-%mem | head -15     # top memory consumers
ps -eo pid,etime,comm                            # elapsed time since start
ps -eo pid,lstart,comm                           # absolute start time

# All threads of a process
ps -T -p 1234
ps -eLf | grep 1234

Process tree#

ps axjf                  # ASCII art tree (BSD)
ps -ejH                  # indented tree (POSIX)
pstree                   # dedicated tool
pstree -p                # with PIDs
pstree -u                # with usernames
pstree -a                # with arguments

Watch processes#

watch -n 1 'ps aux --sort=-%cpu | head -20'

ss β€” Socket Statistics (modern netstat)#

ss is the modern replacement for netstat β€” faster, more features, same basic concepts.

Common invocations#

ss -tuln          # TCP+UDP listening sockets, numeric (most common)
ss -tulnp         # + show process name/PID
ss -ta            # all TCP connections
ss -ua            # all UDP sockets
ss -x             # UNIX domain sockets
ss -s             # summary statistics
ss -i             # TCP internal info (window, RTT)

Option flags#

FlagMeaning
-tTCP sockets
-uUDP sockets
-xUNIX domain sockets
-lListening sockets only
-aAll sockets (listening + connected)
-nNumeric (no DNS/service name resolution)
-pShow process (requires root for others’ processes)
-eExtended info (UID, inode)
-oShow timer info
-rResolve hostnames
-4IPv4 only
-6IPv6 only

Filtering with expressions#

ss -tnp state established                    # established TCP
ss -tnp state time-wait                      # TIME-WAIT
ss -tnp state listening                      # listening
ss -tnp '( dport = :80 or sport = :80 )'    # port 80
ss -tnp dst 10.0.0.1                         # connections to host
ss -tnp src :22                              # connections from port 22
ss -tnp dport :\> :1024                      # dest port > 1024

TCP states#

ESTABLISHED, SYN-SENT, SYN-RECV, FIN-WAIT-1, FIN-WAIT-2, TIME-WAIT, CLOSE, CLOSE-WAIT, LAST-ACK, LISTEN, CLOSING

ss -t state established '( dport = :443 )' # HTTPS connections
ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn  # count by state

What’s listening on a port#

ss -tlnp | grep :8080
ss -tnlp sport = :443
sudo ss -tlnp | grep '"nginx"'   # filter by process name

netstat β€” Legacy (still common)#

netstat is deprecated on Linux (replaced by ss) but still present on macOS, BSD, and older Linux systems.

netstat -tuln          # TCP+UDP listening, numeric (like ss -tuln)
netstat -tunap         # all TCP/UDP + process info
netstat -rn            # routing table
netstat -i             # interface statistics
netstat -s             # summary by protocol
netstat -an            # all connections, numeric

macOS / BSD netstat differences#

# macOS: -p specifies protocol, not process
netstat -anp tcp       # macOS: all TCP (not process info)
netstat -anp udp       # macOS: all UDP

# Get process info on macOS
sudo lsof -i :8080     # what's on port 8080
sudo lsof -i tcp       # all TCP connections

lsof β€” List Open Files / Ports#

lsof -i                          # all network connections
lsof -i :8080                    # what's using port 8080
lsof -i tcp                      # all TCP connections
lsof -i tcp:443                  # port 443 specifically
lsof -i @192.168.1.1             # connections to/from IP
lsof -p 1234                     # files opened by PID 1234
lsof -u alice                    # files opened by user
lsof -c nginx                    # files opened by nginx processes
lsof +D /var/log                 # files open in /var/log tree

Practical recipes#

# What process is listening on port 80?
sudo ss -tlnp | grep ':80 '
sudo lsof -i :80

# All established connections and their process
sudo ss -tnp state established

# Count connections per remote IP
ss -tn state established | awk '{print $5}' | cut -d: -f1 | \
  sort | uniq -c | sort -rn | head -20

# Find zombie processes
ps aux | awk '$8=="Z" {print $2, $11}'

# Kill all processes matching name (safer than killall)
pgrep -x stale-worker | xargs kill -TERM

# Top 10 memory-hungry processes
ps aux --sort=-%mem | awk 'NR<=11 {printf "%-10s %5s %5s %s\n",$1,$3,$4,$11}'

# Watch connection count to port 443
watch -n 2 'ss -tn state established dst :443 | wc -l'

# Find processes with open network connections
sudo lsof -i -n -P | grep ESTABLISHED | awk '{print $1,$9}' | sort -u

[!TIP] On modern Linux, always prefer ss over netstat. ss reads directly from the kernel’s netlink socket (/proc/net/tcp) rather than walking /proc, making it significantly faster on systems with many connections. netstat may not be installed by default.