Linux Process Management: ps, top, kill, and nice
Every program running on a Linux system is a process. When you open a text editor, start a web server, or run a backup script, the kernel creates a process with a unique identifier (PID) and...
Key Insights
- The
pscommand provides snapshots of processes, whiletopoffers real-time monitoring—useps aux --sort=-%cpufor quick CPU hog identification andtopfor interactive troubleshooting - Always send SIGTERM (kill -15) before SIGKILL (kill -9) to allow processes to clean up resources gracefully—force-killing can leave orphaned connections and corrupted data
- Nice values range from -20 (highest priority) to 19 (lowest priority), but lowering nice values requires root access—use this for batch jobs that shouldn’t compete with critical services
Understanding Linux Processes
Every program running on a Linux system is a process. When you open a text editor, start a web server, or run a backup script, the kernel creates a process with a unique identifier (PID) and allocates system resources to it. Understanding how to view, monitor, and control these processes is fundamental to system administration and troubleshooting.
Processes exist in different states: running (actively using CPU), sleeping (waiting for an event or resource), stopped (suspended by a signal), and zombie (completed but waiting for parent to read exit status). Zombie processes are particularly interesting—they consume minimal resources but indicate the parent process isn’t properly handling child termination.
Let’s examine a basic process listing:
ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 169564 13452 ? Ss Jan15 0:42 /sbin/init
www-data 1234 2.3 1.5 523456 62344 ? S 10:23 1:15 nginx: worker
mysql 5678 8.1 4.2 2847392 172584 ? Sl Jan15 45:32 /usr/sbin/mysqld
john 9012 0.0 0.1 21532 5124 pts/0 R+ 14:32 0:00 ps aux
The STAT column reveals process states: S for sleeping, R for running, Z for zombie. Additional characters indicate modifiers: s for session leader, l for multi-threaded, + for foreground process group.
Viewing Processes with ps
The ps command is your primary tool for process inspection. While it has dozens of options, mastering a few key patterns covers most use cases.
The aux options show all processes with user-oriented formatting:
ps aux | grep nginx
www-data 1234 0.5 1.5 523456 62344 ? S 10:23 1:15 nginx: master process
www-data 1235 0.3 0.8 523888 34212 ? S 10:23 0:52 nginx: worker process
For hierarchical views showing parent-child relationships, use the --forest option:
ps -ef --forest
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Jan15 ? 00:00:42 /sbin/init
root 823 1 0 Jan15 ? 00:00:12 \_ /usr/sbin/sshd -D
root 8234 823 0 14:20 ? 00:00:00 \_ sshd: john [priv]
john 8256 8234 0 14:20 ? 00:00:00 \_ sshd: john@pts/0
john 8257 8256 0 14:20 pts/0 00:00:00 \_ -bash
Custom output formatting gives you exactly the information you need:
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu | head -10
PID PPID CMD %MEM %CPU
5678 1 /usr/sbin/mysqld 4.2 8.1
3421 1 /usr/bin/python3 app.py 2.8 5.3
1234 1 nginx: master process 1.5 2.3
This one-liner sorts by CPU usage and displays the top 10 processes—invaluable when investigating performance issues.
Real-Time Monitoring with top
While ps provides snapshots, top offers dynamic, real-time process monitoring. The interface updates every few seconds, showing system-wide statistics and per-process metrics.
top
top - 14:35:42 up 12 days, 4:12, 3 users, load average: 1.23, 1.45, 1.67
Tasks: 247 total, 2 running, 245 sleeping, 0 stopped, 0 zombie
%Cpu(s): 12.5 us, 3.2 sy, 0.0 ni, 83.1 id, 1.2 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 15923.4 total, 2134.2 free, 8456.1 used, 5333.1 buff/cache
MiB Swap: 4096.0 total, 3892.0 free, 204.0 used. 6234.8 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
5678 mysql 20 0 2847392 172584 23456 S 8.1 4.2 45:32.18 mysqld
3421 www-data 20 0 456123 114232 12345 R 5.3 2.8 12:45.67 python3
The load average shows 1, 5, and 15-minute averages. On a 4-core system, values under 4.0 generally indicate healthy load. The CPU line breaks down time spent in user space (us), system/kernel (sy), nice processes (ni), idle (id), and I/O wait (wa).
Interactive commands make top powerful:
- Press
Mto sort by memory usage - Press
Pto sort by CPU usage - Press
kto kill a process - Press
rto renice a process - Press
uthen enter username to filter by user
Filter processes for a specific user:
top -u nginx
For batch mode output suitable for logging:
top -b -n 1 | head -20 > system_snapshot.txt
Consider htop as a more user-friendly alternative with color coding, mouse support, and easier process tree navigation. Install it with your package manager and run htop for an enhanced experience.
Controlling Processes with kill
The kill command doesn’t just terminate processes—it sends signals that processes can handle in different ways. Understanding signals is crucial for graceful process management.
Common signals:
- SIGTERM (15): Polite request to terminate, allows cleanup
- SIGKILL (9): Immediate termination, cannot be caught or ignored
- SIGHUP (1): Hangup signal, often used to reload configuration
- SIGSTOP (19): Pause process execution
- SIGCONT (18): Resume paused process
Always try SIGTERM before SIGKILL:
kill -15 1234
# Wait a few seconds
kill -9 1234 # Only if process didn't terminate
Or use the default (SIGTERM) and escalate:
kill 1234
sleep 5
kill -9 1234
The killall command terminates all processes matching a name:
killall nginx
The pkill command offers pattern matching:
pkill -f "python.*backup.py"
This kills all Python processes with “backup.py” in their command line. The -f flag matches against the full command line, not just the process name.
For more precision, combine with user filtering:
pkill -u www-data -f "php-fpm"
Process Priority with nice and renice
Linux uses nice values to determine CPU scheduling priority. The name comes from the idea that a process with a higher nice value is “nicer” to other processes by demanding less CPU time.
Nice values range from -20 (highest priority) to 19 (lowest priority). Default is 0. Only root can set negative values or lower existing nice values.
Start a process with lower priority:
nice -n 10 ./backup-database.sh
This ensures your backup script doesn’t interfere with production workloads. For CPU-intensive batch jobs, consider even higher values:
nice -n 19 ./video-encoding-job.sh
Adjust a running process with renice:
renice -n 5 -p 1234
Renice all processes owned by a user:
renice -n 10 -u batchuser
View current nice values:
ps -eo pid,ni,cmd | grep myapp
1234 10 /usr/bin/myapp --config prod.conf
1235 0 /usr/bin/myapp --worker
In practice, nice values make the most difference on CPU-bound workloads. I/O-bound processes spend most of their time waiting anyway, so adjusting priority has minimal impact.
Practical Scenarios and Best Practices
Finding Memory Hogs
When your system is running low on memory:
ps aux --sort=-%mem | head -10
Or for a quick one-liner showing the top 5:
ps aux | awk '{print $2, $4, $11}' | sort -k2 -nr | head -6
Automated Process Monitoring
Create a simple watchdog script:
#!/bin/bash
if ! pgrep -f "myapp" > /dev/null; then
echo "$(date): myapp not running, restarting..." >> /var/log/watchdog.log
/usr/local/bin/myapp &
fi
Add to cron for periodic checks:
*/5 * * * * /usr/local/bin/watchdog.sh
Investigating High CPU Usage
Combine top with logging for historical analysis:
while true; do
top -b -n 1 | head -20 >> /var/log/top_snapshots.log
echo "---" >> /var/log/top_snapshots.log
sleep 300
done
Graceful Service Restarts
For services that support configuration reload:
pkill -HUP nginx # Reload nginx configuration
This is far superior to kill/restart cycles that drop connections.
Quick Reference and Next Steps
| Task | Command |
|---|---|
| List all processes | ps aux |
| Find specific process | ps aux | grep name |
| Process tree | ps -ef --forest |
| Real-time monitoring | top or htop |
| Kill gracefully | kill -15 PID |
| Force kill | kill -9 PID |
| Kill by name | pkill name |
| Start with low priority | nice -n 10 command |
| Change priority | renice -n 5 -p PID |
These four commands form the foundation of process management, but modern Linux offers additional tools. Explore systemd for service management, cgroups for resource limiting, and /proc filesystem for deep process inspection. Tools like pstree, pgrep, and pidof complement the core commands covered here.
Master these fundamentals first. When you can quickly identify resource-hungry processes, gracefully terminate misbehaving services, and adjust priorities to prevent system overload, you’ll handle most operational challenges with confidence.