Introduction
Process management is at the heart of Linux system administration. Every running program, service, or command creates one or more processes that consume system resources. Understanding how to view, monitor, control, and optimize these processes is essential for maintaining a healthy, responsive system.
In this comprehensive guide, you'll learn:
- How to list and analyze processes with
ps aux
- Real-time system monitoring with
top
andhtop
- Finding specific processes with
pidof
,pgrep
, andgrep
- Terminating processes using
kill
,killall
, andpkill
with different signals - Managing background and foreground jobs with
jobs
,fg
, andbg
- Controlling process priority with
nice
andrenice
What is a Process? A process is a running instance of a program. When you execute a command or open an application, the operating system creates a process with a unique Process ID (PID) to manage its execution and resources.
Listing All Processes with ps aux
The ps
command displays information about running processes. The most comprehensive view uses ps aux
:
ps aux
Command Breakdown:
ps
: Process status commanda
: Show processes for all usersu
: Display user-oriented format (includes user, CPU%, memory%)x
: Include processes not attached to a terminal (daemons, background services)
Partial Output:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.2 184412 18876 ? Ss 15:41 0:08 /usr/lib/systemd/systemd rhgb --switched-root --system --deserialize 31
root 2 0.0 0.0 0 0 ? S 15:41 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 15:41 0:00 [pool_workqueue_]
centos9 24058 0.0 5.9 52.5g 467916 pts/0 S 18:20 0:22 next-server (v1)
centos9 11143 1.7 5.4 5184512 426996 pts/1 S 10:15 23:01 gnome-shell
centos9 14477 8.6 4.6 32.9g 358820 ? S 11:30 2:49 chrome
Understanding ps aux Output Columns
Column | Meaning | Example | Interpretation |
---|---|---|---|
USER | User who owns the process | root | Process runs as root user |
PID | Process ID (unique identifier) | 1 | First process (init/systemd) |
%CPU | CPU usage percentage | 8.6 | Using 8.6% of CPU |
%MEM | Memory usage percentage | 5.9 | Using 5.9% of RAM |
VSZ | Virtual memory size (KB) | 184412 | ~180 MB virtual memory |
RSS | Resident Set Size - actual RAM used (KB) | 18876 | ~18 MB physical RAM |
TTY | Terminal associated with process | pts/0 or ? | pts/0 = terminal, ? = no terminal (daemon) |
STAT | Process state | Ss | S = sleeping, s = session leader |
START | Time/date process started | 15:41 | Started at 3:41 PM |
TIME | Cumulative CPU time used | 0:08 | Used 8 seconds of CPU time |
COMMAND | Command that started the process | /usr/lib/systemd/systemd | Full command with arguments |
Understanding Process States (STAT)
Code | State | Description |
---|---|---|
R | Running | Currently executing or waiting in run queue |
S | Sleeping (Interruptible) | Waiting for an event (most common) |
D | Sleeping (Uninterruptible) | Usually waiting for I/O (disk, network) |
T | Stopped | Paused by job control signal (Ctrl+Z) |
Z | Zombie | Terminated but not reaped by parent |
I | Idle | Kernel thread (idle state) |
s | Session leader | Process is a session leader |
+ | Foreground | In foreground process group |
< | High priority | Nice value less than 0 |
N | Low priority | Nice value greater than 0 |
Example STAT interpretations:
Ss
: Sleeping, session leader (like systemd)R+
: Running in foregroundSN
: Sleeping with low priority (nice > 0)I<
: Idle kernel thread with high priority
Filtering Processes with grep
To find specific processes, combine ps aux
with grep
:
ps aux | grep nginx
Output:
centos9 30390 0.0 0.0 221672 2552 pts/0 R+ 18:49 0:00 grep --color=auto nginx
Why Only grep Shows Up:
- No nginx process is running
- The
grep nginx
command itself appears in the output - The
R+
state indicates it's running in the foreground (the grep itself)
When nginx is actually running, you'd see:
root 1234 0.0 0.1 125440 8192 ? Ss 10:00 0:00 nginx: master process
www-data 1235 0.0 0.2 125888 16384 ? S 10:00 0:00 nginx: worker process
centos9 5678 0.0 0.0 221672 2552 pts/0 R+ 18:49 0:00 grep --color=auto nginx
To exclude the grep process itself from results, use: ps aux | grep nginx | grep -v grep
or pgrep nginx
Real-Time Monitoring with top
The top
command provides a dynamic, real-time view of system processes and resource usage:
top
Output:
top - 18:50:32 up 3:08, 2 users, load average: 0.37, 0.52, 0.80
Tasks: 297 total, 1 running, 296 sleeping, 0 stopped, 0 zombie
%Cpu(s): 3.8 us, 2.9 sy, 0.0 ni, 88.3 id, 0.1 wa, 4.3 hi, 0.5 si, 0.0 st
MiB Mem : 7680.9 total, 1994.9 free, 3556.0 used, 2568.7 buff/cache
MiB Swap: 8068.0 total, 8068.0 free, 0.0 used. 4124.9 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
24058 centos9 20 0 52.5g 467916 81040 S 0.0 5.9 0:22.86 next-server
11143 centos9 20 0 5184512 426996 159804 S 1.7 5.4 23:01.70 gnome-shell
14477 centos9 20 0 32.9g 358820 238156 S 8.6 4.6 2:49.11 chrome
Understanding top Header
Line 1: System Summary
top - 18:50:32 up 3:08, 2 users, load average: 0.37, 0.52, 0.80
Field | Value | Meaning |
---|---|---|
Current time | 18:50:32 | Current system time |
Uptime | up 3:08 | System running for 3 hours 8 minutes |
Users | 2 users | 2 users logged in |
Load average | 0.37, 0.52, 0.80 | 1-min, 5-min, 15-min average CPU load |
Load Average Interpretation:
0.37
: Last 1 minute average0.52
: Last 5 minutes average0.80
: Last 15 minutes average- Values < 1.0 on single-core = light load
- On 4-core CPU, values < 4.0 = acceptable
- Decreasing trend (0.80 ā 0.37) = load is reducing
Line 2: Task Summary
Tasks: 297 total, 1 running, 296 sleeping, 0 stopped, 0 zombie
- 297 total: Total number of processes
- 1 running: Actively executing (usually just top itself)
- 296 sleeping: Waiting for events (normal)
- 0 stopped: Paused processes (Ctrl+Z)
- 0 zombie: Dead processes awaiting cleanup (should be 0)
Line 3: CPU Usage
%Cpu(s): 3.8 us, 2.9 sy, 0.0 ni, 88.3 id, 0.1 wa, 4.3 hi, 0.5 si, 0.0 st
Metric | Value | Meaning |
---|---|---|
us (user) | 3.8% | CPU time in user space (applications) |
sy (system) | 2.9% | CPU time in kernel space (system calls) |
ni (nice) | 0.0% | CPU time for low-priority processes |
id (idle) | 88.3% | CPU idle time (not in use) |
wa (I/O wait) | 0.1% | Waiting for I/O operations |
hi (hardware IRQ) | 4.3% | Servicing hardware interrupts |
si (software IRQ) | 0.5% | Servicing software interrupts |
st (steal) | 0.0% | Time stolen by hypervisor (VMs only) |
Line 4-5: Memory and Swap
MiB Mem : 7680.9 total, 1994.9 free, 3556.0 used, 2568.7 buff/cache
MiB Swap: 8068.0 total, 8068.0 free, 0.0 used. 4124.9 avail Mem
- Memory: 7.5 GB total, ~2 GB free, ~3.5 GB used, ~2.5 GB for buffers/cache
- Swap: 8 GB swap space, all free (good - means RAM is sufficient)
- avail Mem: ~4 GB available for new applications (includes reclaimable cache)
Interactive top Commands
Key | Action |
---|---|
q | Quit top |
Shift + M | Sort by memory usage |
Shift + P | Sort by CPU usage (default) |
k | Kill a process (prompts for PID) |
r | Renice a process (change priority) |
1 | Show individual CPU cores |
h | Display help |
Press q
to quit top.
Enhanced Monitoring with htop
htop
is an improved, interactive alternative to top
with a color-coded interface and easier navigation:
htop
Installation: If htop is not installed:
- Ubuntu/Debian:
sudo apt install htop
- CentOS/RHEL/Fedora:
sudo dnf install htop
htop Features:
- Color-coded display: CPU, memory, swap usage with visual bars
- Mouse support: Click to select processes
- Tree view: See parent-child process relationships
- Easy sorting: F6 to sort by any column
- Process filtering: F4 to filter processes by name
- Kill processes: F9 to send signals
Navigation:
- Arrow keys to navigate
- F6 to change sort column
- F9 to kill selected process
- F10 or
q
to quit
Finding Process IDs
Using pidof for Running Programs
The pidof
command finds PIDs of running programs by name:
pidof firefox
Output:
31050 31043 31015 30993 30921 30885 30856 30828 30784 30702
What This Shows:
- Firefox is running with multiple processes (10 PIDs)
- Each number is a Process ID
- Multiple processes are normal for modern browsers (multi-process architecture)
- First PID (30702) is typically the main process
Verification with ps:
ps aux | grep firefox
Partial Output:
centos9 30702 69.8 5.7 11827320 455808 ? Sl 18:53 0:27 /usr/lib64/firefox/firefox
centos9 30784 0.2 0.6 273416 52560 ? Sl 18:53 0:00 /usr/lib64/firefox/firefox -contentproc...
centos9 30828 1.9 1.5 2718964 119064 ? Sl 18:53 0:00 /usr/lib64/firefox/firefox -contentproc -childID 1...
Process Breakdown:
- 30702: Main Firefox process (69.8% CPU, 5.7% MEM)
- 30784, 30828, etc.: Child processes for tabs, extensions, content rendering
- Modern browsers use process isolation for security and stability
Using pgrep for Pattern Matching
pgrep
finds processes by pattern (more flexible than pidof):
pgrep sleep
Output:
31193
31233
Shows PIDs of all processes with "sleep" in their command name.
Terminating Processes with kill
The kill
command sends signals to processes, most commonly to terminate them.
Basic Process Termination
kill 31050
What Happens:
- Sends SIGTERM (signal 15) to process 31050
- SIGTERM asks the process to terminate gracefully
- Process can catch the signal and clean up before exiting
- Process may ignore SIGTERM if programmed to do so
Forceful Termination with kill -9
kill -9 31050
Attempting Second Time:
kill -9 31050
Output:
bash: kill: (31050) - No such process
Why This Failed:
- Process 31050 was already terminated by the first
kill
command - Once a process is dead, its PID is freed
- Trying to kill a non-existent PID produces this error
Another Process:
kill -9 31043
About kill -9:
- Sends SIGKILL (signal 9) - forceful termination
- Process cannot catch or ignore SIGKILL
- Kernel immediately terminates the process
- No cleanup, no saving state
- Use only when SIGTERM (15) fails
Warning: kill -9
(SIGKILL) doesn't allow processes to clean up. This can leave:
- Temporary files undeleted
- Database transactions incomplete
- File locks unreleased
Always try
kill
(SIGTERM) first, usekill -9
only if the process doesn't respond.
Common Kill Signals
Signal | Number | Name | Effect |
---|---|---|---|
SIGTERM | 15 | Terminate | Graceful shutdown (default) |
SIGKILL | 9 | Kill | Immediate termination (force) |
SIGHUP | 1 | Hangup | Reload configuration |
SIGINT | 2 | Interrupt | Ctrl+C (interrupt from keyboard) |
SIGSTOP | 19 | Stop | Pause process (cannot be caught) |
SIGCONT | 18 | Continue | Resume stopped process |
Usage Examples:
kill -15 1234 # Graceful termination (same as kill 1234)
kill -9 1234 # Force kill
kill -HUP 1234 # Reload config (common for web servers)
kill -STOP 1234 # Pause process
kill -CONT 1234 # Resume process
Terminating Multiple Processes
Using killall (by Name)
killall firefox
What This Does:
- Finds all processes named "firefox"
- Sends SIGTERM (15) to all of them
- Terminates main Firefox process and all child processes
- Equivalent to killing each PID individually
Force Kill with killall:
killall -9 firefox # Force kill all firefox processes
Using pkill (Pattern Matching)
pkill firefox
pkill vs killall:
killall
: Exact process name matchpkill
: Pattern matching (more flexible)pkill fire
would match "firefox", "firewalld", etc.
Safe Pattern Matching:
pkill -f "firefox" # Match full command line
pkill -u username # Kill all processes by user
pkill -9 -f "script.py" # Force kill Python script
Managing Background and Foreground Jobs
Linux allows you to run processes in the background and switch them between foreground and background.
Running Jobs in Background
sleep 300 &
Output:
[1] 31193
Explanation:
sleep 300
: Command that waits for 300 seconds (5 minutes)&
: Run in background[1]
: Job number (for reference)31193
: Process ID
Listing Jobs
jobs
Output:
[1]+ Running sleep 300 &
Output Breakdown:
[1]
: Job number+
: Current job (most recently started/stopped)Running
: Job statesleep 300 &
: Command
Bringing Jobs to Foreground
fg %1
Output:
sleep 300
What Happens:
fg
: Foreground command%1
: Job number 1- Process now runs in foreground
- Terminal waits for it to complete
- Ctrl+C would terminate it
Pausing with Ctrl+Z:
Press Ctrl+Z
:
Output:
^Z
[1]+ Stopped sleep 300
What Happened:
^Z
: Ctrl+Z signal (SIGTSTP)- Process is paused/stopped (not terminated)
- Returns control to shell
- Process state changes to "Stopped"
Resuming Jobs in Background
bg %1
Output:
[1]+ sleep 300 &
What This Does:
bg
: Background command%1
: Job number 1- Resumes the stopped process
- Runs it in the background
- You can continue using the terminal
Job Control Summary:
- Start job in background:
command &
- List jobs:
jobs
- Bring to foreground:
fg %n
- Pause foreground job:
Ctrl+Z
- Resume in background:
bg %n
- Kill job:
kill %n
Process Priority with nice and renice
Linux uses "nice" values to control process priority. Lower nice values mean higher priority.
Nice Value Range
- -20: Highest priority (least nice to other processes)
- 0: Default priority
- 19: Lowest priority (most nice to other processes)
Starting Process with nice
nice -n 10 sleep 300 &
Output:
[2] 31233
Command Breakdown:
nice
: Set priority for new process-n 10
: Nice value of 10 (lower priority than default 0)sleep 300 &
: Command to run in background[2]
: Job number 231233
: PID
Verification:
pgrep sleep
Output:
31193
31233
Now we have two sleep processes with different priorities.
Changing Priority with renice
The renice
command changes the priority of running processes:
sudo renice -n 15 -p 31193
Output:
31193 (process ID) old priority 0, new priority 15
Command Breakdown:
sudo
: Required to change priority of processes not owned by yourenice
: Change priority command-n 15
: New nice value (15 = lower priority)-p 31193
: Process ID to modify
What Changed:
- Process 31193 originally had nice value 0 (default)
- Now has nice value 15 (much lower priority)
- Will get less CPU time when system is busy
- Won't affect performance when CPU is idle
Regular users can only:
- Increase nice values (lower priority) for their own processes
- Cannot set negative nice values (higher priority)
Root/sudo can:
- Set any nice value (-20 to 19)
- Change priority of any process
Practical Priority Use Cases
Scenario | Nice Value | Example |
---|---|---|
Background batch job | 10 to 19 | nice -n 15 backup.sh & |
Critical real-time app | -20 to -10 | sudo nice -n -15 critical_app |
Video encoding | 10 to 15 | nice -n 12 ffmpeg -i input.mp4... |
Database server | -5 to 0 | sudo nice -n -5 mysqld |
Best Practices for Process Management
Monitoring Best Practices
-
Regular System Checks
- Run
top
orhtop
periodically to check system health - Monitor load average - should be less than number of CPU cores
- Watch for high %wa (I/O wait) - indicates disk bottlenecks
- Check for zombie processes - indicates parent process issues
- Run
-
Resource Identification
- Use
ps aux --sort=-%cpu | head -10
to find CPU hogs - Use
ps aux --sort=-%mem | head -10
to find memory hogs - Monitor processes consistently consuming high resources
- Use
-
Establish Baselines
- Know normal CPU/memory usage for your system
- Document typical load averages
- Identify unusual spikes quickly
Process Termination Best Practices
-
Graceful Termination First
- Always try
kill PID
(SIGTERM) beforekill -9
- Give process time to clean up (5-10 seconds)
- Only use
kill -9
for unresponsive processes
- Always try
-
Verify Before Killing
- Use
ps aux | grep process_name
to confirm PID - Check process owner - don't kill system critical processes
- Understand impact - will this affect other services?
- Use
-
Parent-Child Relationships
- Killing parent may orphan or terminate children
- Some processes respawn automatically (systemd services)
- Use
pstree
to see process tree
Priority Management Best Practices
-
Conservative Priority Changes
- Don't set too many processes to high priority
- Reserve -20 to -10 for truly critical processes
- Use positive nice values for non-urgent tasks
-
Background Jobs
- Always nice background batch jobs:
nice -n 10 command &
- Long-running tasks should have lower priority
- Prevent background jobs from impacting interactive performance
- Always nice background batch jobs:
-
Monitor Impact
- After renicing, check if it improved performance
- Overly high priority can starve other processes
- Balance is key - not everything can be high priority
Safety Practices
-
Never Kill:
- PID 1 (systemd/init) - crashes the system
- Critical system daemons without understanding impact
- Processes you don't recognize without research
-
Be Careful With:
killall
- might match unintended processespkill
with broad patterns- Killing processes as root
-
Before Production:
- Test process management commands in dev/test
- Understand application startup/shutdown procedures
- Document which processes are critical
Command Cheat Sheet
Process Listing and Monitoring
Command | Purpose | Example |
---|---|---|
ps aux | List all processes with details | ps aux | less |
ps aux | grep | Find specific process | ps aux | grep apache |
top | Real-time process monitor | top (press q to quit) |
htop | Interactive process viewer | htop |
pidof | Find PID by program name | pidof nginx |
pgrep | Find PID by pattern | pgrep -u username |
pstree | Display process tree | pstree -p |
Process Termination
Command | Purpose | Example |
---|---|---|
kill PID | Gracefully terminate process | kill 1234 |
kill -9 PID | Force kill process | kill -9 1234 |
kill -HUP PID | Reload process config | kill -HUP 1234 |
killall name | Kill all processes by name | killall firefox |
pkill pattern | Kill processes by pattern | pkill -f script.py |
pkill -u user | Kill all processes by user | pkill -u john |
Job Control
Command | Purpose | Example |
---|---|---|
command & | Run in background | sleep 100 & |
jobs | List background jobs | jobs |
fg %n | Bring job to foreground | fg %1 |
bg %n | Resume job in background | bg %1 |
Ctrl+Z | Suspend foreground job | Press Ctrl+Z |
Ctrl+C | Interrupt foreground job | Press Ctrl+C |
disown %n | Detach job from shell | disown %1 |
Process Priority
Command | Purpose | Example |
---|---|---|
nice -n N command | Start with priority N | nice -n 10 backup.sh |
renice -n N -p PID | Change priority of running process | sudo renice -n 5 -p 1234 |
renice -n N -u user | Change priority for all user processes | sudo renice -n 10 -u john |
Useful ps Command Variations
Command | Purpose |
---|---|
ps aux --sort=-%cpu | head | Top CPU-consuming processes |
ps aux --sort=-%mem | head | Top memory-consuming processes |
ps -u username | Processes for specific user |
ps -ef | Full format listing |
ps -eLf | Show threads |
Summary
In this comprehensive guide, you've mastered Linux process management:
ā
Listing and analyzing processes with ps aux
and understanding its output
ā
Real-time monitoring with top
and htop
for CPU, memory, and system resources
ā
Finding processes using pidof
, pgrep
, and pattern matching
ā
Terminating processes gracefully with kill
and forcefully with kill -9
ā
Using killall
and pkill
for bulk process termination
ā
Managing jobs with &
, jobs
, fg
, bg
, and Ctrl+Z/Ctrl+C
ā
Controlling process priority with nice
and renice
ā
Implementing best practices for monitoring and process control
Process management is essential for system administration, troubleshooting, and optimization. Understanding these tools allows you to maintain responsive, efficient systems and quickly resolve issues.
What's Next?
Expand your system administration skills with these topics:
- systemd Service Management: Control system services with systemctl
- System Logging: Monitor logs with journalctl and syslog
- Resource Limits: Control process resources with ulimit and cgroups
- Performance Tuning: Optimize system performance with sysctl
- Advanced Monitoring: Tools like sar, vmstat, iostat
Master process management to take full control of your Linux systems!