How to Kill a Process in Linux (kill, pkill, killall, and Ports)
Find a stuck or runaway process and stop it: ps and pgrep to find it, kill to stop it politely, kill -9 when it won't, pkill and killall by name, killing whatever is using a port, and why a killed app comes straight back if a process manager runs it.
Sometimes a program hangs, eats all the CPU, or holds a port you need. Stopping it takes two steps: find its process ID (PID), then send it a signal.
Step 1: find the process
ps aux | grep node
deploy 4821 2.1 3.4 1203456 140320 ? Sl 09:12 0:42 node server.js
The second column, 4821, is the PID. (Ignore the line for grep node itself.)
Shorter:
pgrep -a node # list matching PIDs with their command lines
Or interactively with top or htop — sort by CPU or memory to find the culprit. (Basic Linux commands)
Step 2: stop it
Politely first
kill 4821
kill sends SIGTERM by default: "please shut down". Well-behaved programs finish what they're doing, close connections, and exit. (Graceful shutdown in Node.js)
Check it's gone:
ps -p 4821
Forcefully if it won't
kill -9 4821
-9 is SIGKILL: the kernel stops the process immediately. It can't refuse, but it also can't clean up — open files may be left half-written, temporary files left behind, in-flight requests dropped. Use it after SIGTERM has had a few seconds.
By name instead of PID
pkill -f "node server.js" # match against the full command line
killall node # every process named node — careful
killall node stops every Node process, including ones you didn't mean. Prefer pkill -f with a specific pattern.
Kill whatever is using a port
The classic "port 3000 is already in use" fix. Find the process:
sudo lsof -i :3000
# or
sudo ss -tlnp | grep :3000
Then kill its PID. A one-liner:
sudo kill $(sudo lsof -t -i :3000)
Or with fuser:
sudo fuser -k 3000/tcp
(Ports explained, Docker port already allocated)
"I killed it and it came straight back"
That's a process manager doing its job — systemd, PM2, Docker's restart policy or Supervisor restarts the app when it dies. Stop it through the manager instead:
sudo systemctl stop myapp
pm2 stop myapp
docker stop myapp
(What is systemd?, PM2 vs systemd)
Permission denied
You can only kill your own processes. To stop another user's (or root's), use sudo kill. Think twice before killing system processes you don't recognise.
On macOS and Windows
- macOS: the same
ps,kill,pkill,lsofcommands work, or use Activity Monitor. - Windows:
tasklistandtaskkill /PID 4821 /F, or Task Manager. For ports:netstat -ano | findstr :3000.
Signals cheat sheet
| Signal | Number | Meaning |
|---|---|---|
| SIGTERM | 15 | Please stop (default for kill) |
| SIGINT | 2 | Interrupt — what Ctrl+C sends |
| SIGHUP | 1 | Hang up — many servers reload config on it |
| SIGKILL | 9 | Stop now, no clean-up |
Before you reach for kill -9
If an app keeps hanging or using too much memory, killing it treats the symptom. Check the logs for why. (Finding memory leaks in Node.js, How container CPU and memory limits work)
EasySpawn runs your apps under a process manager that restarts them if they crash, and Claude Code can find and stop a runaway process for you from a plain-English request. See how it works or join the waitlist.
Related: Basic Linux Commands · What Is systemd? · What Is an IP Address and a Port? · PM2 vs systemd
Keep reading
DNS Propagation Explained: Why Domain Changes Take Time (and How to Speed Them Up)
You changed a DNS record and your site still points to the old place. What "DNS propagation" really is (caching, not spreading), how TTL controls the wait, why nameserver changes take longest, how to check from different places, and how to flush your own cache.
Why Is My Website Slow? A Beginner's Guide to Finding Out
Slow sites lose visitors. How to measure speed properly, what Core Web Vitals mean, and the usual culprits in AI-built apps — huge images, too much JavaScript, slow database queries, waterfalls of API calls, and a server far from your users — with a fix for each.