Back to lessons

Apple Terminal

Find What Is Using a Local Dev Port

A local server will not start because another process is already listening on the same TCP port.

Command

lsof -nP -iTCP:3000 -sTCP:LISTEN

What changed

Nothing changes. The command reports the process listening on the port.

Danger

safe

When to use it

Use when Vite, Next.js, Rails, Django, or another local server refuses to bind to a port.

When not to use it

Do not use it to inspect remote servers. It only checks the local Mac.

Undo or recovery

No undo needed because this command is read-only.

Expected output

A row showing the command name, PID, user, and LISTEN socket for port 3000.

demo script

Disposable terminal steps

  1. printf '%s\n' 'COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME' 'node 4242 uri 23u IPv6 0xabc 0t0 TCP *:3000 (LISTEN)'
  2. printf '%s\n' 'COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME' 'node 4242 uri 23u IPv6 0xabc 0t0 TCP *:3000 (LISTEN)' | awk 'NR==1 || /LISTEN/'

simulated output

What it looks like

disposable vessel
::fixture-ready::
$ printf '%s\n' 'COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME' 'node 4242 uri 23u IPv6 0xabc 0t0 TCP *:3000 (LISTEN)'
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 4242 uri 23u IPv6 0xabc 0t0 TCP *:3000 (LISTEN)
::exit-code::0
$ printf '%s\n' 'COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME' 'node 4242 uri 23u IPv6 0xabc 0t0 TCP *:3000 (LISTEN)' | awk 'NR==1 || /LISTEN/'
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 4242 uri 23u IPv6 0xabc 0t0 TCP *:3000 (LISTEN)
::exit-code::0

YouTube Short

Port 3000 busy?

When your Mac says a dev port is already in use, do not guess. lsof shows the process and PID that owns it.

LinkedIn hook

Your dev server says port 3000 is busy. Ask macOS who is holding it.

Question: What is your fastest habit for debugging EADDRINUSE on macOS?

experiments

A/B tests to run

Metric: shorts_retention_3s

A: Lead with the EADDRINUSE error.

B: Lead with the lsof command immediately.