# 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.

Updated: 2026-10-19 · Tested on: MacBook Pro 14" (M1 Pro, 16 GB), macOS 26.3 Tahoe (also checked: Next.js 14.2 dev server, three Node.js 22 servers and one Python 3 http.server running at once) · Applies to: macOS 12 Monterey – 26 Tahoe · Author: Tu Nguyen, OneClickTool Studio

## Short answer

- 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 `&` or `nohup`.
- 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 <kbd>Ctrl</kbd> <kbd>C</kbd>. 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 node` and `pkill 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](https://oneclicktool.app/fix/developer/port-3000-already-in-use-mac) 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](https://oneclicktool.app/macos/ram-rescue).

## Make it a habit

- Stop a server with <kbd>Ctrl</kbd> <kbd>C</kbd> before closing its tab.
- Give each project a fixed port in its `package.json` script, 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](https://oneclicktool.app/fix/slow-mac/kernel-task-high-cpu).

## 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

- [lsof(8) manual page](https://keith.github.io/xcode-man-pages/lsof.8.html)
- [View information about Mac processes in Activity Monitor — Apple Support](https://support.apple.com/guide/activity-monitor/view-information-about-processes-actmntr1001/mac)
- [Next.js CLI: next dev — Next.js documentation](https://nextjs.org/docs/app/api-reference/cli/next)

Source: https://oneclicktool.app/fix/developer/kill-forgotten-dev-servers-mac
