Skip to main content
Navigation
HomeTechnical ReferenceJournalGitHubGitHub
Sidebar — toggle document categories via the logo
Categories

Process Management

Overview

Every running program on a Linux system is a process. Managing processes — listing them, inspecting their resource consumption, sending signals, adjusting priorities, and controlling services — is a fundamental operations skill. This reference covers the core tools and commands for process management, from quick health checks to deep debugging.

Process inspection

Listing processes

ps takes a snapshot of running processes. The aux and -ef forms are the two most common, and -o lets you choose exactly which columns to display.

ps aux # all processes, BSD-style output
ps -ef # all processes, Unix-style output
ps -e -o pid,ppid,user,%cpu,%mem,cmd # custom columns

ps -u www-data # processes for a specific user
ps -C nginx # processes matching command name
ps --ppid 1234 # child processes of PID 1234
ps -eo pid,ppid,cmd --forest # process tree

Common ps columns

FlagColumnDescription
%cpuCPU usagePercentage of CPU time
%memMemory usagePercentage of physical memory
vszVirtual sizeVirtual memory in KB
rssResident sizePhysical memory in KB
statStateProcess state code
startStart timeWhen the process began
timeCPU timeCumulative CPU time
lstartFull startExact start timestamp
nlwpThreadsNumber of threads

Process states

CodeStateMeaning
RRunningExecuting or in run queue
SSleepingWaiting for an event (interruptible)
DUninterruptible sleepWaiting for I/O (usually disk)
ZZombieTerminated but not reaped by parent
TStoppedSuspended by signal or debugger
tTracing stopPaused by ptrace
<High priorityReal-time or niceness < 0
NLow priorityNiceness > 0

Interactive process viewers

Interactive viewers refresh continuously and let you sort and act on processes with keystrokes. top ships with every system; htop, btm, and glances add color, mouse support, and more detail.

top # classic interactive process viewer
htop # improved color viewer (install separately)
btm # bottom — modern TUI resource monitor
glances # comprehensive system monitor (Python-based)

top interactive keys:

KeyAction
1Toggle per-CPU view
MSort by memory usage
PSort by CPU usage
cToggle full command path
kKill a process (prompts for PID and signal)
rRenice a process
fSelect displayed columns
uFilter by user
qQuit

Finding process PIDs

pgrep and pidof find a process's PID by name, user, or command-line pattern — handy before signaling it or inspecting its resources.

pgrep nginx # list PIDs matching pattern
pgrep -u www-data -f wsgi # by user and full command line
pgrep -l nginx # show process name alongside PID
pidof nginx # list PIDs by exact binary name

Sending signals

Signals tell a process to perform a specific action. The default signal for kill is TERM (15).

Common signals

NumberNameAction
1SIGHUPHangup — often used to reload configuration
2SIGINTInterrupt from keyboard (Ctrl+C)
3SIGQUITQuit with core dump
9SIGKILLKill immediately (cannot be caught or ignored)
15SIGTERMTerminate gracefully (default)
17SIGCHLDChild process terminated
18SIGCONTContinue if stopped
19SIGSTOPStop process (cannot be caught)
kill 1234 # send SIGTERM to PID 1234
kill -9 1234 # force kill (SIGKILL)
kill -HUP 1234 # reload (SIGHUP)
kill -STOP 1234 # pause process
kill -CONT 1234 # resume process

killall nginx # kill all processes named nginx
killall -HUP nginx # reload all nginx processes

pkill -f "python app.py" # kill by command-line pattern
pkill -u www-data # kill all processes for user

kill -l # list all signal names

Process priority (niceness)

Nice values range from -20 (highest priority) to 19 (lowest priority). Default is 0. Only root can set negative values.

nice -n 10 my_command # start with lower priority
nice -n -5 my_command # start with higher priority (root)

renice -n 5 -p 1234 # change priority of running process
renice -n -10 -u www-data # change priority for all user processes

ionice -c 2 -n 0 -p 1234 # set I/O scheduling class

I/O classes: 1 = real-time, 2 = best-effort (default), 3 = idle.

systemd service management

systemd is the init system and service manager on modern Linux distributions. Services are defined in unit files and managed with systemctl.

Service lifecycle commands

systemctl controls services: start, stop, restart, reload configuration, and enable them to start automatically at boot.

systemctl start nginx # start a service
systemctl stop nginx # stop a service
systemctl restart nginx # restart a service
systemctl reload nginx # reload configuration (SIGHUP)
systemctl reload-or-restart nginx # reload if supported, else restart
systemctl enable nginx # enable at boot
systemctl disable nginx # disable at boot
systemctl enable --now nginx # enable and start
systemctl mask nginx # prevent service from starting
systemctl unmask nginx # allow service to start again

Status and inspection

These commands report whether a service is running and enabled, list service units, and reveal a unit's full properties and definition.

systemctl status nginx # detailed service status
systemctl is-active nginx # active or inactive
systemctl is-enabled nginx # enabled or disabled
systemctl is-failed nginx # check if in failed state
systemctl list-units --type=service # list all service units
systemctl list-units --type=service --state=failed # list failed services
systemctl list-unit-files --type=service # list all installed services
systemctl show nginx # all service properties
systemctl cat nginx # show unit file contents

Journal inspection for services

journalctl filters the system journal to a specific service's output — the first stop when a service fails to start or misbehaves.

journalctl -u nginx # all logs for the service
journalctl -u nginx --since "1 hour ago" # recent logs
journalctl -u nginx -f # follow logs
journalctl -u nginx -p err # errors only

Writing a systemd service unit

A unit file defines how and when a service runs: its description, dependencies, the process to launch, restart policy, and environment. Place it in /etc/systemd/system/ and run systemctl daemon-reload to register it.

# /etc/systemd/system/myapp.service
[Unit]
Description=My Application
After=network.target
Requires=postgresql.service

[Service]
Type=simple
User=app
Group=app
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/server
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
EnvironmentFile=/etc/myapp/env.conf
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

Service types

TypeBehavior
simpleProcess is the main service (default); systemd assumes it starts immediately.
forkingProcess forks and exits; parent PID expected to exit.
oneshotShort-lived process; systemd waits for it to exit.
notifyLike simple, but sends sd_notify when ready.
idleLike simple, but waits until no more jobs are active.

After creating or editing a unit:

systemctl daemon-reload # reload unit definitions
systemctl start myapp
systemctl enable myapp

Resource monitoring

CPU and memory

These tools summarize overall memory and load. mpstat breaks CPU usage down per core, and pidstat attributes it to individual processes.

free -h # memory usage summary
free -h -s 5 # refresh every 5 seconds
uptime # load averages (1, 5, 15 min)

mpstat 1 # per-CPU statistics
mpstat -P ALL 1 # all CPUs individually
pidstat 1 # per-process CPU stats
pidstat -u -p 1234 1 # specific PID

Memory analysis

free and /proc/meminfo show totals; vmstat tracks memory pressure over time; pmap and smem drill into how a single process uses memory.

cat /proc/meminfo # detailed memory information
vmstat 1 # virtual memory statistics
pmap 1234 # memory map of a process
smem -k # proportional memory usage (install smem)

Disk I/O

iostat measures disk throughput and utilization, while iotop identifies which processes are reading and writing. /proc/<pid>/fd/ and lsof show the files a process has open.

iostat -x 1 # extended disk I/O stats
iotop -o # top for I/O (sorted by usage)
ls -l /proc/1234/fd/ # open file descriptors
lsof -p 1234 # list open files for process

Network per process

ss with -p links sockets to the processes that own them. nethogs and iftop show live bandwidth use by process and by connection.

ss -tlnp # TCP listeners with process info
ss -tunap # all TCP/UDP sockets with process
nethogs eth0 # bandwidth by process (install nethogs)
iftop -i eth0 # bandwidth by connection (install iftop)

/proc filesystem

The /proc virtual filesystem exposes process and kernel information.

/proc/cpuinfo # CPU details
/proc/meminfo # memory statistics
/proc/loadavg # load averages
/proc/uptime # system uptime
/proc/version # kernel version
/proc/sys/ # kernel tunables (sysctl)

# Per-process:
/proc/<pid>/cmdline # command line (null-separated)
/proc/<pid>/environ # environment variables (null-separated)
/proc/<pid>/fd/ # open file descriptors
/proc/<pid>/status # process status and resource usage
/proc/<pid>/limits # resource limits
/proc/<pid>/cgroup # cgroup membership
/proc/<pid>/io # I/O statistics
/proc/<pid>/oom_score # OOM-killer score (0-1000, higher = more likely to kill)
/proc/<pid>/oom_score_adj # OOM score adjustment (-1000 to 1000)

Troubleshooting patterns

These ready-made command pipelines answer the common questions: what is eating CPU or memory, which process holds a port, which processes are zombie or stuck, and what a process is actually doing.

# Find what's using the most CPU
ps aux --sort=-%cpu | head -10

# Find what's using the most memory
ps aux --sort=-%rss | head -10

# Find zombie processes (state Z: terminated but not yet reaped by parent)
ps aux | awk '$8 ~ /Z/'

# Find process by listening port
ss -tlnp | grep ':80'

# Check if a process is stuck in D state
cat /proc/1234/status | grep State

# Trace system calls
strace -p 1234 # attach to running process
strace -p 1234 -e trace=network # trace only network syscalls
strace -c -p 1234 # summary counts

# Trace library calls
ltrace -p 1234

# Inspect child processes
pstree -p 1234

See also