How to kill the process on a port on Mac

Use lsof to get the PID, then kill. Know when kill -9 and pkill are the wrong tool.

macOS has no built-in command that kills a process by port. You do it in two steps: find the PID with lsof, then send it a signal with kill.

The short answer

kill $(lsof -ti tcp:8080 -sTCP:LISTEN)

Replace 8080 with your port. lsof -t prints only the PID of the process that listens on that port, and kill receives it.

The same thing in two steps

lsof -nP -iTCP:8080 -sTCP:LISTEN
kill 51207

Read the first command's output before you run the second. It shows the command name, the PID and the user. If the process belongs to another user or to the system, kill fails with Operation not permitted. Do not reach for sudo until you know what the process is. Some processes are protected by System Integrity Protection, and sudo cannot stop those.

kill and kill -9

  • kill PID sends SIGTERM (signal 15). The process can catch it, close files, remove lock files and stop its children.
  • kill -9 PID sends SIGKILL. The kernel ends the process at once. The process gets no chance to clean up.

Start with plain kill and wait a few seconds. Use kill -9 only when the process ignores SIGTERM or hangs. After kill -9, child processes can survive, and temp files and lock files stay on disk. Never use it on a database that is still working. You can corrupt data.

The port is free, then it comes back

A task runner such as nodemon, pnpm or npm can start the server again when you kill only the listener. Check the parent:

ps -p 51207 -o pid,ppid,command
ps -p 51190 -o pid,ppid,command   # the ppid from the first line

Then stop the parent. Do not use a process group kill (kill -- -PGID) on a dev server you started from a terminal. It shares its group with your shell, and you close the shell too.

pkill and killall

These match by name, not by port. Preview first:

pgrep -fl vite      # list matches, with full command lines
pkill -f vite       # stop them

-f matches the whole command line, so pkill -f vite can also hit vitepress or a path with vite in it. killall node stops every process named node, including other projects and tools that run on Node. Use these when you want to stop a whole family. Use lsof when you want one port.

Without lsof

These npm tools take a port and kill what listens on it. They need Node:

npx kill-port 3000
npx fkill :3000

To keep it in your shell, add this function to ~/.zshrc:

killport() { kill $(lsof -ti tcp:"$1" -sTCP:LISTEN) }

Then run killport 3000.

Do it in one click with Portfox

Portfox lists the listeners on your Mac with the service name, version and project folder. To free a port, find the row and click Stop.

  • It signals the process that started the service, for example pnpm dev, so a wrapper does not restart it.
  • It never signals a process group. The search for that process stops at your shell, your terminal or any app.
  • Force Stop (SIGKILL) is a separate action.
  • Restart stops the service and runs the same command again in Terminal, iTerm2 or Warp, in the same folder.
brew install --cask xergic/tap/portfox

No Homebrew? Download the app from portfox.kandera.cz/download. Portfox needs macOS 15 or later and an Apple Silicon Mac. It is free and open source (MIT).

See every dev server and port on your Mac for the full list view.