When an application hangs, spins a CPU core to 100%, or leaves “stuck” subprocesses behind, you’ll need the right Linux terminal tools to identify and terminate it cleanly. This guide shows the safest and most effective ways to kill processes in Linux, how to spot and handle zombie processes, how to find CPU hogs, and how to monitor processes in general. It’s written for busy engineers and power users who want reliable, copy‑pasteable commands that work across distros.

TL;DR (Cheat Sheet)

  • List processes:
    • ps aux
    • ps -eo pid,ppid,user,stat,pcpu,pmem,etime,cmd –sort=-pcpu
    • top or htop
  • Find PID by name:
    • pgrep -fl “name”
  • Kill safely:
    • kill -15 PID # SIGTERM (polite)
    • kill -9 PID # SIGKILL (force, last resort)
    • pkill -f “pattern” # Kill by command line
    • killall program # Kill by executable name
  • Find CPU hogs:
    • top (sort by %CPU)
    • ps -eo pid,comm,%cpu –sort=-%cpu | head
    • pidstat -u 1
  • Find zombies:
    • ps -eo pid,ppid,stat,comm | awk ‘$3 ~ /Z/ {print}’
  • Kill by port:
    • fuser -k 8080/tcp
    • lsof -i :8080
  • Service-managed processes:
    • systemctl stop NAME
    • systemctl restart NAME

Understand Linux Signals (Why kill sometimes “doesn’t work”)

Killing a process is really about sending it a signal:

  • SIGTERM (15): Ask the process to exit cleanly. Preferred first step.
  • SIGINT (2): Similar to pressing Ctrl+C in a terminal.
  • SIGHUP (1): Often used to reload/restart daemons (depends on program).
  • SIGKILL (9): Immediate termination. The kernel stops the process without cleanup. Use only if SIGTERM fails.
  • SIGQUIT (3): Ask to quit and dump core for debugging.

Order of escalation: SIGTERM → wait → SIGKILL if needed.

Some processes won’t die because:

  • They’re in uninterruptible sleep (D state), usually stuck in I/O or NFS; not killable until the kernel completes the operation.
  • A supervisor (systemd, Docker, Kubernetes) keeps restarting them. You must stop them via the supervisor.

Read More: Check Disk Space by Directory in Linux

The Safest, Most Reliable Way to Kill a Process

  1. Identify the process accurately:
    • By name:pgrep -fl “myapp” Add -u USER to scope to one user. Use -x for exact matches:pgrep -x myapp
    • By port (web servers, dev servers, etc.):lsof -i :8080 fuser 8080/tcp
  2. Attempt graceful termination (SIGTERM):

    kill -15 <PID>

    Or by pattern:

    pkill -f “myapp –flag”

    Or by executable name:

    killall myapp

    Safer variant using pgrep → kill (preview before firing):

    pgrep -fl “myapp” pgrep -f “myapp” | xargs -r kill -15

  3. Verify it stopped:

    pgrep -f “myapp” || echo “Stopped”

  4. Escalate only if needed (SIGKILL):

    kill -9 <PID>

    For process groups (kills the whole foreground job started in a shell):

    kill — -<PGID> # Note the minus sign before PGID

    Get PGID:

    ps -o pid,pgid,cmd -p <PID>

  5. If systemd manages it, stop/restart the service (preferred):

    systemctl status myapp.service sudo systemctl stop myapp.service sudo systemctl restart myapp.service

    Stopping the unit prevents immediate respawn.

  6. If a process won’t die and STAT shows D (uninterruptible I/O), diagnose I/O:
    • Check mounts and storage:mount | column -t dmesg | tail -n 50
    • Resolve the I/O issue (e.g., restore NFS, fix disk), then try kill again.

Pro tip: Use renice to reduce impact while you investigate:

sudo renice +15 -p <PID>

And limit CPU cores to contain a runaway job:

taskset -cp 0,1 <PID>

How to Find and Handle Zombie Processes

A zombie (defunct) process has finished execution but its parent hasn’t read its exit status yet. It shows up with STAT=Z and cannot be killed—because it’s already dead. The fix is to get the parent to reap it, or let systemd adopt and reap it if the parent exits.

  • Detect zombies:ps -eo pid,ppid,user,stat,etime,comm | awk ‘$4 ~ /^Z/ {print}’ Or:ps -el | awk ‘$2 ~ /Z/ {print}’ top # look for ‘Z’ in the STAT column
  • Inspect the parent that should reap it:ps -o ppid= -p <ZOMBIE_PID> ps -fp <PPID>
  • Remediation options:
    • Restart or gracefully stop the parent so it calls wait() and reaps children:kill -TERM <PPID> # or if service-managed: sudo systemctl restart parent.service
    • If the parent is hung or not going to reap, stopping it will hand zombies to PID 1 (systemd), which will reap them automatically.
    • Avoid SIGKILL on zombies themselves—it won’t change anything. The target is the parent.

Common causes: buggy daemon code that doesn’t wait() on children, mismanaged shells that spawn and forget, and crash loops.

How to Find Processes Eating All Available CPU

When a workstation fans up or a server misses SLOs, quickly identify CPU hogs.

  • Live view (interactive):
    • top
      • Press Shift+P to sort by CPU.
      • Press 1 to view per-core usage (helpful to see if one core is pegged).
    • htop
      • F6 to sort by CPU, tree view to see parent/child relations; search with /
  • One-liners for quick snapshots:ps -eo pid,ppid,comm,%cpu,%mem,stat –sort=-%cpu | head pidstat -u 1 # per-process CPU usage every second
  • For kernel/user hotspots (advanced):perf top # live profiling (needs sudo on many systems)
  • Confirm what a PID is doing:pstree -p <PID> strace -p <PID> -f -tt -o /tmp/trace.txt # attach briefly, then Ctrl+C

After identifying the culprit:

  • Try to gracefully end it:kill -TERM <PID>
  • If it must keep running but behave better:
    • Lower its priority:sudo renice +10 -p <PID>
    • Restrict CPUs:taskset -cp 2-3 <PID>
  • If it’s a service:sudo systemctl reload <service> # if supported sudo systemctl restart <service>

Read More: Guide to Firewalld in Linux

Monitoring Processes in General (Practical Toolkit)

Healthy systems are monitored continuously. Here are reliable approaches from quick TTY checks to always-on observability.

  • Interactive monitors:
    • top: Built-in, zero-dependency. Sort by CPU (P), memory (M), time (T).
    • htop: Nicer UI, tree view, search, kill from within the UI.
    • atop/glances: Broad system view (CPU, mem, disk, net, processes).
  • ps snapshots (great in scripts and with watch):

    watch -n 1 ‘ps -eo pid,ppid,user,stat,pcpu,pmem,etime,cmd –sort=-pcpu | head -n 20’

    Useful STAT codes:

    • R: running
    • S: sleeping
    • D: uninterruptible I/O sleep
    • T: stopped
    • Z: zombie
  • Per-user or per-cgroup views:

    ps -u <user> -o pid,stat,pcpu,pmem,cmd –sort=-pcpu | head systemd-cgtop # live CPU/memory I/O by control group (services/containers) systemd-cgls # show cgroup hierarchy

  • Memory-focused:

    ps -eo pid,comm,rss,vsz,%mem –sort=-%mem | head pmap -x <PID> | tail -n 10

  • I/O and file handles:

    iotop -o # top processes by I/O (requires sudo) lsof -p <PID> # open files/sockets for a process

  • Network-bound processes (to pair with CPU checks):

    ss -tulpn # listening sockets with PIDs lsof -i :443

  • Systemd services and logs (the real source of truth for daemons):

    systemctl status <service> journalctl -u <service> -e -f

  • Containers (if using Docker):

    docker top <container> docker stats docker inspect –format ‘{{.State.Pid}}’ <container> | xargs -I{} ps -fp {}

  • Historical/per-second utilization (great for “it spiked earlier”):

    pidstat -u -p ALL 1 mpstat -P ALL 1

Best Practices and Safety Tips

  • Prefer graceful termination first. SIGTERM allows cleanup: release ports, flush buffers, close files.
  • Validate your target before killing:pgrep -fl “pattern” ps -fp <PID>
  • Beware of overly broad pkill/killall patterns. Use -x (exact), -u (user), or -n (newest) to narrow the scope:pkill -x -u myuser myapp pkill -n -f “myapp –staging”
  • When a process is part of a service, use systemctl. Killing the binary may lead to immediate respawn by the manager.
  • For runaway jobs, reduce impact with renice/taskset while you investigate root cause via logs, strace, or profiling.
  • If you see many zombies, the issue is the parent process. Restart or fix that parent, not the zombies.
  • Processes stuck in D state aren’t killable. Fix the underlying I/O or filesystem first.

Practical Scenarios You’ll Meet (and What to Run)

  • Kill a Node/Java/Python dev server on port 3000/8080:fuser -k 3000/tcp # or lsof -ti :8080 | xargs -r kill -15
  • Kill the newest instance of a process by name:pgrep -n -f “myapp” | xargs -r kill -15
  • Kill everything started by your current shell job (foreground job control):jobs -l # get PGID from a job kill — -<PGID>
  • Monitor top 10 CPU consumers every second:watch -n 1 ‘ps -eo pid,ppid,user,stat,pcpu,pmem,cmd –sort=-pcpu | head’
  • Find and inspect zombies, then address their parent:ps -eo pid,ppid,stat,cmd | awk ‘$3 ~ /^Z/ {print}’ # Then: ps -fp <PPID> sudo systemctl restart <parent-service>

Closing Thoughts

On Linux, killing a process is easy; killing the right process the right way is what prevents data loss and repeated outages. Start with SIGTERM, escalate only when needed, and use your service manager for daemons. To keep systems steady, pair termination skills with good observability—top/htop for quick triage, ps/pidstat for scripted snapshots, and systemd tools for managed workloads. With the commands above, you can quickly identify, monitor, and resolve CPU hogs, zombies, and misbehaving services from the terminal.

FAQs: Killing Processes on Linux

  • What is the best way to kill a process in Linux?
    • Identify → SIGTERM → verify → SIGKILL if necessary. Prefer systemctl for services.
  • What’s the difference between kill, pkill, and killall?
    • kill targets a PID. pkill targets by pattern/attributes. killall targets by exact executable name. pkill and killall may hit multiple processes—scope them carefully.
  • Why doesn’t kill -9 always work?
    • It always works unless the process is in D state (uninterruptible I/O) or you lack permission. D state resolves only when the kernel completes the I/O.
  • How do I kill a process that keeps respawning?
    • Stop or disable the supervisor that restarts it (systemd services, containers, cron jobs). Use systemctl stop NAME or stop the container.
  • Can I prevent a CPU hog from starving the system while I debug?
    • Yes: renice to a lower priority and/or pin it to specific cores with taskset.
{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}
>