Find and stop forgotten localhost dev servers on your Mac
List every dev server still running on your Mac with its port, uptime, memory and folder, then stop the ones you forgot. One command, tested on macOS 26.
- Forgotten dev servers keep running after you close a terminal tab, an editor window or an AI agent session, and each one holds memory and a port.
- The command lsof -nP -iTCP -sTCP:LISTEN lists every process listening on a port, including your dev servers.
- A Next.js 14 dev server on our test Mac held 667 MB of memory after loading two pages.
- Stop one server with kill and its PID, or stop every Node listener at once with kill $(lsof -t -iTCP -sTCP:LISTEN -a -c node); the -a flag matters, because without it lsof matches every listener.
Why dev servers get forgotten#
Every web project starts a local server: npm run dev, next dev, vite, rails s, python -m http.server. You open it in a browser, work, and move on. The server often does not move on with you:
- You closed the terminal tab but the server was started with
&ornohup. - It runs inside a VS Code or Cursor window that is minimized on another desktop.
- An AI coding agent started it in a background shell to check its work, and the session ended.
Each one keeps its port, which is why you later hit "port 3000 already in use", and its memory. It also keeps watching your files and rebuilds when they change.
Step 1: list every dev server with one command#
This lists every process you own that is listening on a TCP port:
lsof -nP -iTCP -sTCP:LISTEN -a -u "$USER"
The list includes normal apps too: on our Mac, ControlCenter (AirPlay on ports 5000 and 7000), Notion, the GitHub app and VS Code helpers all listen locally. To see only dev servers, filter by the runtimes that run them. Paste this into Terminal (zsh or bash) to print a clean table with the port, PID, uptime, memory and project folder:
lsof -nP -iTCP -sTCP:LISTEN -a -u "$USER" -c node -c Python -c python -c ruby -c php -c java -c deno -c bun |
awk 'NR>1{n=split($9,a,":"); print a[n], $2}' | sort -un |
while read port pid; do
printf "%-6s %-7s %-10s %5s MB %s\n" "$port" "$pid" "$(ps -o etime= -p $pid | xargs)" \
"$(( $(ps -o rss= -p $pid) / 1024 ))" "$(lsof -a -p $pid -d cwd -Fn | sed -n 's/^n//p')"
done
On our test Mac, with a Next.js site, three small Node servers and a Python server running, it printed:
3000 54115 00:41 28 MB ~/scratch/demo
3001 54319 00:21 132 MB ~/DATA/PROJECTS/…/One-Click-Tool-geo
5173 54116 00:41 28 MB ~/scratch/demo
8000 54118 00:41 11 MB ~/scratch/demo
8080 54117 00:41 28 MB ~/scratch/demo
Paths are shortened here; the demo servers ran from a scratch folder. The last column is the folder each server was started in, which is the fastest way to tell which project it belongs to. It ran in about a tenth of a second.
Two details we hit while testing: lsof names the process by its executable, so Next.js shows up as node even though Activity Monitor calls it next-server. And Python from python.org or Homebrew shows up as Python with a capital P, which is why both spellings are in the filter.
Step 2: check how much memory they really hold#
Dev servers are heavier than they look. We loaded two pages of a Next.js 14 site and measured the server:
| Server | Memory right after use | Memory after ~1 minute idle |
|---|---|---|
Next.js 14.2 dev server (next dev) |
667 MB (whole process group: 797 MB) | 132 MB |
| Minimal Node.js 22 HTTP server | 40 MB | 28 MB |
Python 3 http.server |
— | 11 MB |
The drop after a minute is macOS compressing memory that sits unused. The server still owns that memory, and gets it back the moment you save a file and it rebuilds. Three or four forgotten framework servers can easily hold 1–2 GB between them.
Step 3: stop the ones you forgot#
Stop one server with its PID from the table:
kill 54319
kill asks the process to stop normally, the same as Ctrl C. Use kill -9 54319 only if it ignores that.
To stop every Node.js server that is listening on a port, and nothing else:
kill $(lsof -t -nP -iTCP -sTCP:LISTEN -a -u "$USER" -c node)
Add -c Python to include Python servers. On our test Mac, with -c Python added, it stopped all five servers, including the Next.js one and its child process, in about a second; running the list again printed nothing.
Avoid
killall nodeandpkill node. They stop every process with "node" in its name, including editor language servers and helper tools, without showing you what you hit.
If a port still looks busy after this, see port 3000 already in use for single-port checks and the AirPlay case on port 5000.
Prefer a window to a command?#
Activity Monitor shows the same processes if you search for node, with their memory, but it has no column for ports or project folders, so you cannot tell which server is which. That is the gap we built RAM Rescue to fill. Its Localhost tab lists every open port with a health dot, memory and uptime, and a Stop button on each row; a Projects view starts and stops what you build with a live log. The Memory tab also flags dev processes left behind by closed terminals, with a Quit all button. RAM Rescue is free and open source, signed and notarized; see the RAM Rescue page.
Make it a habit#
- Stop a server with Ctrl C before closing its tab.
- Give each project a fixed port in its
package.jsonscript, so a clash tells you which project is still running. - Run the list command at the end of the day, or whenever your Mac starts to feel slow. If the slowness stays, see why kernel_task uses so much CPU.
RAM Rescue shows the apps using your Mac's memory as big cards with a Quit button, finds dev processes left behind by closed terminals, and cleans caches apps rebuild by themselves. Pro watches memory from the menu bar: it warns you before your Mac slows down and catches apps that leak memory..
FAQ
Why do dev servers keep running after I close the terminal?
Closing a terminal usually stops the processes it started, but not always. Servers started with nohup or a trailing &, by VS Code tasks, by process managers, or by an AI coding agent's background shell can outlive the window. They keep their port and memory until you stop them or restart the Mac.
Should I use killall node?
Avoid it. killall node stops every process named node, which can include language servers and helper tools, and it does not show you what you are stopping. Filtering by listening ports, as in this guide, only touches servers.
How much memory does a dev server use?
It depends on the framework and the project. On our Mac a Next.js 14 dev server held 667 MB right after loading two pages, while a minimal Node server used about 40 MB. macOS compresses memory that sits idle, so the number you see later can be lower.
Do idle dev servers slow down my Mac?
An idle server uses little CPU, but it still holds memory and keeps watching your project files, so it wakes up and rebuilds every time a file changes. Several forgotten servers add up, especially on a 16 GB Mac running Xcode, Docker or a browser with many tabs.
Sources
- Oct 19, 2026: First published. Command and memory numbers measured on macOS 26.3 with Next.js 14.2 and Node 22.
Keep reading
Port 3000 already in use on Mac? Find what is using it and stop it
Fix EADDRINUSE on port 3000 (or 5173, 8080) on a Mac: one lsof command shows the process and its project folder, then stop it safely. Tested on macOS 26.
How to delete duplicate files on Mac safely, with a way to undo
Find true duplicates by content, keep the right copy, and send the rest to the Trash so you can undo. Terminal method and apps with undo, tested on macOS 26.
Can't empty Trash on Mac because a file is in use? How to fix it
Find which app is holding a file in the Trash, unlock locked items, use Delete Immediately, and fix Trash on external drives. Tested on macOS 26 Tahoe.