Manfath / Blog / Find a port on Mac Terminal

How to find a port on Mac Terminal

You hit npm run dev, see "port 3000 already in use", and now you need to know who's holding it — from the Mac Terminal. Here are the three reliable terminal commands for mapping a port back to a process on macOS, and which one to reach for in which situation.

How do I find a port on Mac Terminal?

Open Terminal (Cmd+Space → "Terminal" → Return) and run a single command:

lsof -nP -iTCP:3000 -sTCP:LISTEN

Replace 3000 with the port you want. The PID column is the process ID. The COMMAND column is the program name. lsof is preinstalled on every macOS version — no Homebrew, no npm install, no setup.

The short answer

In the Mac Terminal, run:

lsof -nP -iTCP:3000 -sTCP:LISTEN

Replace 3000 with the port you care about. The output looks like this:

COMMAND    PID    USER   FD   TYPE  DEVICE    NAME
node     54231 khalouf  23u  IPv6 0x...  TCP *:3000 (LISTEN)

The PID column (54231 here) is your answer. That's the process holding port 3000.

The longer answer (and why)

1. lsof — the right default

lsof ("list open files") ships with macOS. Despite the name, it lists open everything — files, sockets, pipes, network connections. Sockets are files in Unix, so listening ports show up here.

The flags worth knowing:

If you're scripting, -t gives you just the PID:

lsof -ti :3000     # bare PID, suitable for piping

That's the form you'll see in the famous one-liner kill -9 $(lsof -ti :3000).

2. netstat — when lsof is unavailable

netstat on macOS is BSD-flavored and doesn't have the -p flag that Linux users expect. You can list listening sockets with:

netstat -anv -p tcp | grep LISTEN

You won't see process names here, but you'll see every listening port at once — useful when you don't yet know which port is in question.

To go from a port back to a PID, fall back to lsof. There's no good native way to do it with netstat alone on macOS.

3. ss — note: not on macOS

If you're coming from Linux, you might be reaching for ss -ltnp. Don't. ss isn't installed on macOS by default and isn't worth installing — lsof already does the job. (You can brew install iproute2mac if muscle memory demands it, but it's a wrapper.)

4. The Activity Monitor route

Activity Monitor (Cmd+Space → "Activity Monitor") lets you see all running processes with a Network tab. It's good for confirming what a PID corresponds to, but it doesn't let you query by port. You still need lsof first to find the PID, then Activity Monitor to inspect it.

Common gotchas

Empty output

If lsof -i :3000 returns nothing, three things to check:

  1. Is the server actually running? Check with ps aux | grep node (or whatever runtime you're using).
  2. Is it listening on TCP, not UDP? Try lsof -i :3000 without the TCP qualifier.
  3. Was it started under another user? If sudo, you may need sudo lsof -i :3000 to see it.

Multiple PIDs

If lsof returns several rows for one port, you're usually looking at a parent + child (e.g. a Node cluster, or a webpack-dev-server that forked workers). The first PID is typically the one you want; the rest die with it on signal.

IPv6 vs IPv4

macOS prefers IPv6. A server bound to :: shows up under TYPE IPv6. lsof -iTCP:3000 matches both, so this is rarely a problem — but if you're seeing the port in a browser and not in lsof, double-check you're not filtering one family out.

Skip the typing.
Manfath sits in your menu bar and shows every listening port — TCP, UDP, IPv4, IPv6 — with the process name and PID behind each one. Refreshed every 3 seconds. Free and open source.

Once you have the PID

What you do next depends on intent:

One-liners worth saving

# Who has port 3000?
lsof -nP -iTCP:3000 -sTCP:LISTEN

# Bare PID (for scripting)
lsof -ti :3000

# All listening TCP ports on the machine, sorted
lsof -nP -iTCP -sTCP:LISTEN | tail -n +2 | sort

# Kill whoever has port 3000 (gracefully, then forcefully)
PID=$(lsof -ti :3000) && kill $PID; sleep 2; kill -9 $PID 2>/dev/null

Read next