Type a port and get the exact command to find and kill what is using it, on Windows, Linux and macOS.
This tool builds the exact command to free a port that is already in use, the one a hung dev server or a leftover process is holding when you hit EADDRINUSE. Type the port number, pick your operating system, and it gives you both steps: the command that lists the process and its PID, and the command that ends it, plus a single line version for when you just want the port back. It covers Windows (netstat and taskkill, with a PowerShell one liner), Linux and macOS (lsof and kill), and it updates live as you change the port. Everything is generated in your browser, so it is just the right command to copy, never anything sent anywhere.
100% in your browser. Nothing you type ever leaves this page.
Find the PID, then end it
Two moves. Find the process holding the port, then stop it. The rest is syntax, and syntax is where every operating system decided to go its own way.
Windows puts the owning PID in the last column of netstat, so you read it off and hand it to taskkill.
netstat -ano | findstr :3000
taskkill /PID 12345 /F
PowerShell skips the copy and paste step: Stop-Process -Id (Get-NetTCPConnection -LocalPort 3000).OwningProcess -Force. Handy when you already have a PowerShell prompt open, overkill when you don’t.
Linux and macOS both answer to lsof. We use the long form on purpose. The short lsof -i :3000 also matches outbound connections to port 3000, which sends you chasing a browser tab instead of the server you meant to stop.
lsof -nP -iTCP:3000 -sTCP:LISTEN
kill 12345
One line, if you trust what is on the port: kill -9 $(lsof -ti:3000). Linux carries two extras that macOS doesn’t ship at all, ss -ltnp and fuser -k 3000/tcp. People copy those onto a Mac constantly and get "command not found", then assume something is broken.
Permissions bite the same way everywhere. Listing is usually fine as yourself. Ending a process you don’t own wants Administrator on Windows and sudo elsewhere. Anything below port 1024 belongs to root, so lsof -i :80 as a normal user returns an empty result. That’s not "nothing is listening". That’s nothing you’re allowed to see. Add sudo and look again.
On macOS, ports 5000 and 7000 are already taken
This one costs people an afternoon, and it’s not their fault.
Since Monterey, macOS runs AirPlay Receiver, and it holds port 5000. Port 7000 as well. So a Flask app, or anything else that defaults to 5000, refuses to start on a Mac and the error tells you nothing useful. Run the lsof above and you’ll see ControlCe sitting on the port. That’s Control Center, a system process. Force-killing it does nothing lasting, because launchd brings it straight back.
Two ways out. Turn the receiver off under System Settings, General, AirDrop and Handoff, AirPlay Receiver (older macOS keeps it in System Preferences, Sharing). Or move your app to another port. Honestly we move the app. Disabling a system feature so a dev server can keep its default port is the wrong trade, and six months later nobody remembers doing it.
Docker is the other regular offender. A container that looks stopped can still leave a published port bound, and lsof points at com.docke rather than anything you recognise. Run docker ps first, then docker stop. Killing the Docker helper process isn’t the fix and it tends to take your other containers with it.
Graceful first, force second
The commands above use the forceful stop, because that’s what people search for when a port won’t free up. For a hung dev server it’s exactly right. Nothing is mid-write, nothing holds a lock, and you want your port back.
It’s the wrong default for anything that owns data. kill -9 sends SIGKILL, which a process can’t catch, so it never gets to flush a buffer or release a lock. Databases and queue workers should go down through their own shutdown command. If the process is one of yours, its own stop command is always tidier than a kill. Force is for things that are genuinely stuck, not for the first attempt.
Frequently asked questions
How do I kill a process on a port on a Mac?
Run lsof -nP -iTCP:3000 -sTCP:LISTEN to get the PID, then kill 12345 with that number, or kill -9 $(lsof -ti:3000) in one go. Two macOS specifics catch people out. Ports 5000 and 7000 are held by AirPlay Receiver since Monterey, and the process you’ll see is ControlCe, so that’s a settings change rather than a kill. And fuser and ss, which every Linux answer suggests, aren’t installed on macOS.
Why does macOS say port 5000 is in use when nothing is running?
AirPlay Receiver. macOS Monterey and later bind ports 5000 and 7000 for it out of the box, which collides with the default port of several development servers, Flask being the famous one. Turn it off under System Settings, General, AirDrop and Handoff, AirPlay Receiver, or run your app on another port. Killing the process behind it doesn’t stick, since the system restarts it.
Why does it say the port is already in use (EADDRINUSE)?
Because another process is already listening there, and an operating system lets only one process bind a TCP port at a time. Usually it’s an old copy of your own server that didn’t shut down cleanly, or a container still holding the port. Find the PID, confirm it’s what you think it is, then stop it. If the port frees up and the error persists, check whether you’re binding to 127.0.0.1 in one place and 0.0.0.0 in another.
What is the difference between kill and kill -9?
Plain kill sends SIGTERM, a request to shut down that the process can handle, so it flushes files and closes sockets on the way out. kill -9 sends SIGKILL, which can’t be caught or ignored, so the process dies immediately and can leave half-written data or a stale lock behind. Try the polite one first. Reach for -9 when the process refuses to exit.
Do I need administrator or sudo?
To end a process you don’t own, yes. On Windows, run the terminal as Administrator when taskkill reports access denied. On Linux and macOS, put sudo in front of the kill when the process belongs to another user or to root. You also need it to see processes on ports below 1024, which is why lsof -i :80 looks empty until you add sudo.











