Back to the blog
DevTools· Jul 13, 2026· 6 min read

Port already in use? How to find and kill the process on any port (Windows, macOS, Linux)

EADDRINUSE: address already in use is the most common dev-server error there is. Here's how to find and kill the offending process on every OS — and how to stop doing it by hand.

#cli#debugging#windows#linux#productivity

You run your dev server and get EADDRINUSE: address already in use :::3000. Something is squatting on your port — usually a zombie process from a dev server that didn't shut down cleanly, a container you forgot about, or another project you had open last week. Here's the fastest way to find and kill it on every operating system.

macOS and Linux: lsof + kill

# Find the process listening on port 3000
lsof -i :3000

# Output shows the PID - kill it
kill -9 <PID>

# Or as a one-liner
kill -9 $(lsof -ti :3000)

The -t flag makes lsof print only the PID, which is what makes the one-liner work. Prefer plain kill (SIGTERM) first if you want the process to shut down gracefully; -9 (SIGKILL) is the hammer for processes that ignore polite requests. On Linux servers without lsof, `fuser -k 3000/tcp` or `ss -lptn 'sport = :3000'` do the same job.

Windows: netstat + taskkill

# Find the PID listening on port 3000
netstat -ano | findstr :3000

# Kill it (the PID is the last column)
taskkill /PID <PID> /F

# PowerShell one-liner
Get-Process -Id (Get-NetTCPConnection -LocalPort 3000).OwningProcess | Stop-Process -Force

Watch the state column in netstat output: you want the row that says LISTENING, not TIME_WAIT. TIME_WAIT entries are already-closed connections the OS is draining — they clear on their own and killing their former owner won't help.

Why this keeps happening

  • Dev servers killed with the terminal's X button instead of Ctrl+C don't always release their socket - the process outlives the window.
  • nodemon/watch-mode restarts can orphan the child process while the parent respawns, leaving two processes contending for the port.
  • Docker containers with published ports hold the host port until the container stops - `docker ps` is worth a look before you start killing PIDs.
  • VS Code's integrated terminals keep background tasks alive after the editor window closes, especially on Windows.

Stop doing this by hand

If you do this more than once a week, script it or use a tool built for it. This exact annoyance is why we built PortSlayer — run pk with no arguments and you get a full-screen dashboard of every listening port, searchable, with kill-with-confirmation on a single keystroke. It's free and MIT-licensed, works on Windows and Linux, and also speaks JSON for scripts. But even a shell alias for the one-liner above will save you the ritual of googling this page again next month.

# ~/.bashrc or ~/.zshrc
killport() {
  kill -9 $(lsof -ti :"$1") && echo "Killed process on port $1"
}

# Usage
killport 3000

One prevention tip

Most dev servers accept a fallback port or pick a free one automatically (Vite does this out of the box). If yours doesn't, wire your start script to check the port first and fail with a useful message instead of a stack trace. Your future self at 9am Monday will thank you.

Written by Appesto Engineering.