Find and stop the dev servers your coding agent left running
Updated · Tested on macOS 27
Coding agents like Claude Code, Codex, and Cursor start dev servers, test watchers, and build processes in the background. When the session ends, those processes often keep running: holding ports, using memory, and rebuilding on every save. Here is how to find them on a Mac and stop them without breaking the agent itself.
Why they keep running
An agent runs commands such as npm run dev or tsc --watch through a shell. When the agent or its terminal closes, the shell goes away but its long-running child doesn't have to. macOS hands such a process to launchd, so its parent process ID (PPID) becomes 1. That orphaned process runs until you stop it or restart the Mac.
1. Dev servers still holding a port
lsof -nP -iTCP -sTCP:LISTENThis lists every process of yours listening on a TCP port. Apps like your editor, Docker, or Spotify appear too; the leftovers are usually node, Python, ruby, bun, or deno on ports like 3000, 5173, 8000, or 8080. To stop one, see how to find and kill the process using a port.
2. Orphaned watchers and workers without a port
Watchers and queue workers don't listen on a port, so look for runtimes whose parent is gone:
ps -xo pid,ppid,etime,comm | awk 'NR==1 || ($2 == 1 && $4 ~ /(^|\/)(node|python[0-9.]*|Python|ruby|bun|deno)$/)'ps -x includes your processes that have no terminal, comm is the executable path, and the awk filter keeps runtimes with PPID 1. The pattern matches the executable's whole name on purpose: a looser filter like /bun/ also matches system processes whose path contains .bundle.
ETIME is how long each one has been running. Not every match is a leftover: Homebrew services and other launch agents also run with PPID 1. Check brew services list before stopping something you set up on purpose.
3. See which project a process belongs to
ps -o pid,etime,command -p <PID>
lsof -a -d cwd -p <PID>The full command shows what was run, and the working directory is usually the project it was started from. That is enough to tell the next dev from a closed task apart from one you are using right now.
4. Leave the agent's own tools alone
A running agent or editor also starts processes for itself: MCP servers, language servers, and file indexers. Stopping those breaks the session that is still open. Check the parent first:
ps -o ppid= -p <PID> # prints the parent's PID
ps -o pid,command -p <PPID>If the parent is the agent (claude, codex, a Cursor process) or your editor, and the process is not a dev server you asked for, leave it. It goes away when the agent exits. Processes with PPID 1 have no parent left, so they are safe to consider.
5. Stop the leftovers
pgrep -P <PID> # list its child processes first
kill <PID>kill sends SIGTERM so the process can shut down its own children. If pgrep -P still lists children a few seconds later, stop those by PID too. Use kill -9 only for a process that ignores SIGTERM.
Keeping it from happening
- Ask the agent to stop any server it started before it finishes, or to report the PIDs it left running.
- Start long-running dev servers in your own terminal and let the agent use them, instead of letting it launch its own.
- Check for leftovers when a port is unexpectedly busy or the Mac's fans spin up with nothing open.
DevPorts does these checks continuously in the menu bar. Its Background section lists orphaned and port-less dev processes, tags which agent or terminal started each one, and it never lists or stops the agents, editors, and terminals themselves.