---
title: "Find and kill a port process on Mac with Portman | Ian Nuttall"
description: "A free macOS menu bar app that shows every listening port, which project owns it, and whether it's actually still alive. Kill the ones you forgot. Open source."
canonical: "https://ian.is/portman"
language: "en"
---

# Find and kill ports still running dev servers on your Mac with Portman

A menu bar app that names every dev server on your Mac, and kills the ones you forgot.

[Download for macOS](https://github.com/iannuttall/portman/releases/latest)v0.2.0 · 4.2 MB · macOS 15+

[Star on GitHub](https://github.com/iannuttall/portman)

1 star · Open source

[Verify the download](https://github.com/iannuttall/portman#verify-the-download)

Search ports, projects, frameworks…

servers listening

## What Portman shows you that lsof doesn't

### Named, not node (pid 10791)

Not node (pid 10791). The project, the framework and its version, read from package.json, lockfiles and Vite's dep cache.

### Port in use but nothing answers

A server holding its port but no longer answering looks healthy everywhere else. Portman probes each one and says so.

### Conflicts grouped by port

When two things fight over 3000 they get their own heading, with both contenders listed so you can see which to keep.

### Preview what each port serves

Expand a row for a live thumbnail of localhost, so you can tell which of your six Astro servers is the one you wanted.

### Kill orphaned dev servers

Servers whose project folder is gone, and the ones agent worktrees left behind, fold away with a single Kill all.

### Share a port publicly

One click opens a Cloudflare tunnel and copies a public URL, with the Host header rewritten so your dev server accepts it.

## Killing a port from the terminal

Two commands, no app required. Find what's holding the port, then stop it by process id. Change the port below and the commands update.

PortUsing 3000 until that's a port between 1 and 65535.

1\. See what's on the port

```
lsof -i :3000
```

The `PID`column is the process id you want.

2\. Stop it

```
kill 10791
```

Swap in the id from step 1. Add `-9` only if it ignores you, since that skips cleanup.

Or both at once

```
lsof -ti:3000 | xargs kill
```

Fine when you already know the port is yours. It kills everything listening there without telling you what any of it was, which is the part Portman exists to fix.

## What Portman can read, and what it sends

A port manager needs real access to your machine, and you should be suspicious of anything that asks for it. So all of this is checkable.

Nothing leaves your Mac

No analytics, no telemetry, no accounts. The only network requests are to your own localhost ports, and to Cloudflare if you explicitly share one.

Signed and notarised by Apple

So macOS can verify it hasn't been tampered with since I built it.

Open source, MIT licensed

Every line is on [GitHub](https://github.com/iannuttall/portman), including the build scripts. Build it yourself if you'd rather.

Verify what you downloaded

Run this against the file you downloaded. The expected value is in the [release notes](https://github.com/iannuttall/portman/releases/latest) for that version.

```
shasum -a 256 portman-0.2.0.dmg
```

## Common questions about killing ports

Almost always a dev server you started earlier and never stopped. Closing the terminal tab doesn't always take the process with it, and anything started by an editor task or a background agent outlives the window you launched it from. Run `lsof -i :3000` and you'll see what's holding it.

Same two commands, different number. `lsof -i :8080` to find the process id, then `kill <pid>`. Port 8080 is usually a Java or Spring app, a proxy, or a container publishing a port, so check what it is before you stop it.

Node's way of saying the port you asked for is taken. The address is already bound by another process, so your server can't start. Free the port or start on a different one.

Usually because the process belongs to another user or to root, and `lsof` only shows you your own by default. Try `sudo lsof -i :3000`. The other case is a process that has died but left the socket in TIME\_WAIT, which clears on its own after a minute or so.

`kill` sends SIGTERM, which asks the process to shut down and lets it clean up first. `kill -9` sends SIGKILL, which the process can't catch or ignore, so it dies immediately without flushing anything or removing its own files. Start with `kill` and only escalate if it doesn't respond.

Not for your own processes, which covers nearly every dev server. You need `sudo` for anything owned by root or another user, and `kill` returns an `EPERM` error rather than silently failing. Portman shows that error instead of pretending the kill worked.

Killing the process won't help, because the port belongs to the Docker daemon rather than the container. Stop the container instead: `docker stop <name>`. Portman resolves forwarded ports back to the container and compose service, and offers Stop container rather than a kill that would take Docker Desktop down with it.

The commands do, with small differences. Linux has `lsof` and also `fuser -k 3000/tcp`, which finds and kills in one step. Windows uses `netstat -ano | findstr :3000` then `taskkill /PID <pid> /F`. Portman itself is macOS only.

From the terminal, `lsof -ti:3000,3001,5173 | xargs kill` handles a list. In Portman, search or use a `/regex/` and the footer offers to kill everything matching, which is the same idea without having to know the port numbers first.

## Free, open source, and it stays out of your way.

[Download for macOS](https://github.com/iannuttall/portman/releases/latest)v0.2.0 · 4.2 MB · macOS 15+

[Star on GitHub](https://github.com/iannuttall/portman)

1 star · Open source

[Verify the download](https://github.com/iannuttall/portman#verify-the-download)
