How to Kill a Process in Linux: The Complete Guide to kill, pkill, and Signals
A frozen application, a runaway script eating all your CPU, a hung service that won’t restart — sooner or later, every Linux administrator needs to terminate a process by hand. Knowing how to kill a process in Linux is one of the most fundamental skills in server administration, yet most people only ever learn the blunt instrument (`kill -9`) and never the precise tools that prevent data loss.
This guide walks through the entire workflow: how to find the process you want to stop, how to kill it by PID or by name, what the signals actually mean, and — crucially — the *right order* to send them so you don’t corrupt the very data the process was managing.
Key Takeaways
• To kill a process, first find its PID with `ps aux | grep`, `pgrep`, `top`, or `htop`, then send it a signal with `kill`.
• The plain `kill` command sends SIGTERM (15) — a polite request to shut down cleanly. This is the correct first move almost every time.
• `kill -9` sends SIGKILL, which forcibly terminates the process with no cleanup. Use it only as a last resort.
• Kill by name with `pkill name` or `killall name` when you don’t want to look up the PID.
• Always try SIGTERM first, then escalate to SIGKILL only if the process refuses to die.
For broader context on managing services, users, and resources, see our pillar guide to Linux server administration.
How do you find the process you want to kill?
You can’t kill a process until you know its PID (Process ID), the unique number the kernel assigns to every running process. There are several ways to find it.
The classic approach is `ps aux` piped into `grep`:
“`bash
ps aux | grep nginx
“`
The second column is the PID — that’s the number you’ll feed to `kill`. One annoyance: `grep` often matches *itself* in the output. Filter it out like this:
“`bash
ps aux | grep [n]ginx “`
A cleaner, purpose-built tool is `pgrep`, which returns just the PIDs:
“`bash
pgrep nginx
pgrep -a nginx
pgrep -f “python myscript.py” “`
For an interactive, live view, use `top` (installed everywhere) or `htop` (nicer, often needs installing):
“`bash
top
htop “`
In `top`, press `k`, type the PID, and choose a signal. In `htop`, highlight a process, press F9, and pick the signal from the menu. These are ideal when you’re hunting down *what* is hammering the server, not just stopping something you already know.
How do you kill a process by its PID?
Once you have the PID, the simplest command is:
“`bash
kill 4821 “`
That’s it. Notice there’s no `-9`, no flags — just `kill
If you want to be explicit, these three commands are identical:
“`bash kill 4821 # default signal is SIGTERM kill -15 4821 # SIGTERM by number kill -TERM 4821 # SIGTERM by name “`
What are Linux signals, and which ones matter?
A “signal” is a small message the kernel delivers to a process telling it to do something. `kill` doesn’t actually *kill* anything by itself — it sends a signal, and the process decides how to respond. You can list every signal with `kill -l`. In practice, three matter most for terminating processes.
| Signal | Number | What it does | When to use it |
|---|---|---|---|
| SIGTERM | 15 | Polite request to terminate. The process can catch it, clean up (flush data, close files, release locks), and exit gracefully. This is the default. | Almost always — your first choice. |
| SIGKILL | 9 | Force kill. Cannot be caught, blocked, or ignored. The kernel terminates the process instantly with no cleanup. | Last resort, when SIGTERM is ignored. |
| SIGHUP | 1 | “Hang up.” Historically a terminal disconnect; many daemons treat it as “reload your config” instead of dying. | Reloading a service (e.g. nginx) without a full restart. |
The syntax is the same for all of them — just change the number or name:
“`bash kill -15 4821 # SIGTERM (graceful) kill -9 4821 # SIGKILL (force) kill -1 4821 # SIGHUP (often a config reload) kill -HUP 4821 # same thing, by name “`
The reflexive `kill -9` that everyone reaches for is actually the wrong first move — and understanding why makes you a better administrator.
`kill -9` sends SIGKILL, which the process *cannot catch, block, or handle*. The kernel simply terminates it instantly. That sounds like exactly what you want when something is stuck — but here’s the catch: the process gets no chance to clean up. It can’t flush unsaved data to disk, close open files properly, release locks it’s holding, or finish a database transaction it was halfway through. So `kill -9` can leave behind corrupted files, stuck lock files, orphaned resources, or a half-written database.
The default `kill` (SIGTERM, signal 15) does the opposite: it politely *asks* the process to shut down, giving it the chance to save its work, close cleanly, and exit gracefully — which is what you want almost every single time.
The correct sequence is: send SIGTERM first (just `kill
How do you force kill a process with kill -9?
Sometimes a process is genuinely hung — it has stopped responding to signals entirely and SIGTERM does nothing. *That* is when SIGKILL is appropriate:
“`bash
kill -9 4821
kill -KILL 4821 “`
Because SIGKILL can’t be intercepted, the process has no say in the matter — it’s gone the instant the kernel processes the signal. Use it knowing you may be discarding whatever that process was holding in memory. If you find yourself needing `kill -9` regularly for the same service, that’s a bug to investigate, not a routine to normalize.
How do you kill a process by name instead of PID?
Looking up PIDs gets tedious. Two commands let you target processes by name directly.
`pkill` sends a signal to every process matching a pattern:
“`bash
pkill nginx
pkill -9 nginx
pkill -f “python myscript.py”
pkill -u danish node “`
`killall` is similar but matches the exact process name by default (less fuzzy than `pkill`):
“`bash
killall firefox
killall -9 firefox
killall -i firefox “`
The same SIGTERM-first discipline applies here: run `pkill nginx` (graceful) before `pkill -9 nginx` (force).
How do you kill all processes of a user or pattern?
When you need to clear out everything a user or pattern owns — say, before deleting an account or cleaning up a misbehaving deployment:
“`bash
pkill -u danish
pkill -9 -u danish
killall -u danish
pkill -f “celery worker” “`
Be extremely careful running these as root — `pkill -u root` or an overly broad pattern can take down critical system services. Always double-check your match first with the read-only `pgrep`:
“`bash
pgrep -u danish -l pgrep -af “celery worker” “`
What’s the right order: SIGTERM before SIGKILL?
This is the single most important habit to build. The correct escalation is:
“`bash
kill 4821
sleep 3 ps -p 4821
kill -9 4821 “`
Most well-behaved programs exit within a second or two of SIGTERM. Giving them that brief window is what lets a database commit its transaction, a web server finish in-flight requests, and an editor save your buffer. Jumping straight to `-9` skips all of that. The rule of thumb: graceful first, forceful only when graceful fails.
Manage your Linux processes with full root control
Properly finding, signaling, and killing processes requires real access to your server — something shared hosting rarely gives you. DarazHost VPS and dedicated servers give you full root to monitor and manage processes properly: find them, signal them, and kill them with the right tools, exactly as this guide describes. And because mistakes happen — a forced kill that goes wrong, a service that won’t come back — every plan includes automatic backups so even a `kill -9` that corrupts something has a safety net. That’s real server control, backed by 24/7 support whenever you need a second set of hands.
What about zombie and unkillable processes?
Occasionally a process simply won’t die, even with `kill -9`. Two common causes:
- Zombie processes (state `Z` in `ps`): these are already *dead* — they’ve finished executing but their parent hasn’t read their exit status yet. You can’t kill a zombie because there’s nothing left to kill. The fix is to signal or restart the parent process so it reaps the child:
“`bash
ps aux | grep ‘Z’ ps -o ppid= -p 4821 # get the parent’s PID, then signal the parent “`
- Uninterruptible sleep (state `D`): a process stuck waiting on I/O (often a hung disk or network mount) ignores *all* signals, including SIGKILL, until the I/O completes or times out. No signal will move it — you typically have to fix the underlying I/O issue or, worst case, reboot.
How do you confirm the process actually died?
Never assume the kill worked — verify it:
“`bash
ps -p 4821
pgrep nginx # returns nothing if no match
kill 4821 && sleep 2 && ps -p 4821 || echo “Process 4821 is dead.” “`
If `ps -p
Frequently Asked Questions
What is the difference between kill and kill -9 in Linux? Plain `kill
How do I kill a process by name in Linux? Use `pkill name` or `killall name`. For example, `pkill firefox` sends SIGTERM to all matching processes. Add `-9` to force, or `-f` (with `pkill`) to match the full command line for scripts.
Why won’t kill -9 stop my process? The process is likely a zombie (already dead, waiting to be reaped by its parent) or stuck in uninterruptible sleep (state `D`, blocked on I/O). Neither can be killed by signals. Restart the parent for zombies, or resolve the I/O problem for `D`-state processes.
How do I find the PID of a process? Use `ps aux | grep
Is it safe to use kill -9 by default? No. SIGKILL skips all cleanup, which can corrupt files, leave stale locks, or break a database mid-transaction. Always try SIGTERM first and only escalate to `-9` when a process is genuinely hung.