Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Port Management

Find processes using ports, kill stale listeners, and resolve port conflicts. A common developer pain point solved.

Platform: macOS/Linux Use Case: “What’s using port 3000?” / “Kill whatever’s blocking my server”

Mindset: Design Rules say “silence when nothing to say” - only report conflicts that need action.

Resource Hint: sonnet - Port scanning and process identification.

When to Use

  • Dev server fails to start with “port already in use” error
  • After a crash left orphan processes holding ports open
  • Before starting a multi-service stack to ensure ports are free

Quick Commands

Find What’s Using a Port

# Single port
lsof -i :3000

# Multiple ports
lsof -i :3000 -i :8080 -i :5432

# All listening ports
lsof -i -P | grep LISTEN

Kill Process on Port

# Find and kill (interactive)
lsof -ti :3000 | xargs kill -9

# Or two-step (safer)
lsof -i :3000  # Note the PID
kill -9 <PID>

Execution Flow

┌─────────────────────────────────────────────────────────────┐
│  1. SCAN         List all listening ports                   │
│         ↓                                                   │
│  2. IDENTIFY     Show process name, PID, user for each      │
│         ↓                                                   │
│  3. CATEGORIZE   Group by: dev servers, databases, system   │
│         ↓                                                   │
│  4. SELECT       User picks which to investigate/kill       │
│         ↓                                                   │
│  5. CONFIRM      Show full process details before kill      │
│         ↓                                                   │
│  6. EXECUTE      Kill selected processes                    │
└─────────────────────────────────────────────────────────────┘

Step 1: Scan All Listening Ports

# Comprehensive port scan with process details
lsof -i -P -n | grep LISTEN | awk '{print $1, $2, $9}' | sort -u

# Alternative using netstat (shows more detail)
netstat -anv | grep LISTEN

# macOS-specific: show all TCP listeners
sudo lsof -iTCP -sTCP:LISTEN -P -n

Output format:

COMMAND    PID    ADDRESS
node       12345  *:3000
postgres   67890  127.0.0.1:5432
redis      11111  *:6379

Step 2: Common Port Categories

Development Servers

PortTypical Use
3000React, Rails, Express default
3001React secondary
4000Phoenix, custom
5000Flask default
5173Vite default
8000Django, Python HTTP
8080Alternative HTTP, Java
8888Jupyter

Databases

PortService
5432PostgreSQL
3306MySQL
27017MongoDB
6379Redis
9200Elasticsearch

System Services

PortService
22SSH
80HTTP
443HTTPS
53DNS

Step 3: Investigate Specific Port

# Full details about port 3000
lsof -i :3000

# Show process tree (what spawned it)
ps -f $(lsof -ti :3000)

# Show process start time and command
ps -p $(lsof -ti :3000) -o pid,lstart,command

Step 4: Kill Strategies

Safe Kill (SIGTERM)

# Graceful shutdown - process can cleanup
kill $(lsof -ti :3000)

Force Kill (SIGKILL)

# Immediate termination - no cleanup
kill -9 $(lsof -ti :3000)

Kill All on Port Range

# Kill everything on ports 3000-3010
for port in {3000..3010}; do
  lsof -ti :$port | xargs kill -9 2>/dev/null
done

Common Scenarios

Scenario: “Port already in use”

# Find what's using it
lsof -i :3000

# If it's a zombie process from crashed dev server
kill -9 $(lsof -ti :3000)

# Verify it's free
lsof -i :3000  # Should return nothing

Scenario: Clean Slate for Development

# Kill common dev server ports
for port in 3000 3001 4000 5000 5173 8000 8080; do
  PID=$(lsof -ti :$port 2>/dev/null)
  if [ -n "$PID" ]; then
    echo "Killing process on port $port (PID: $PID)"
    kill -9 $PID
  fi
done

Scenario: Find Rogue Node Processes

# Find all node processes listening
lsof -i -P | grep node | grep LISTEN

# Kill all node listeners
pkill -f node

Scenario: Docker Port Conflicts

# List Docker port mappings
docker ps --format "table {{.Names}}\t{{.Ports}}"

# Stop container using port
docker stop $(docker ps -q --filter "publish=3000")

User Interaction Flow

When executing this playbook:

  1. Scan - Show all listening ports with process names
  2. Categorize - Group into dev servers, databases, system
  3. Ask - “Which ports do you want to investigate or free up?”
  4. Confirm - Show full process details before any kill
  5. Execute - Kill with user’s chosen method (graceful vs force)

AskUserQuestion Structure

Action Selection:

Question: "What would you like to do?"
Options:
  - Scan all listening ports
  - Free specific port (I'll ask which)
  - Kill all dev server ports (3000, 5173, 8080, etc.)
  - Show me what's using the most ports

Troubleshooting

IssueSolution
“Permission denied” on lsofUse sudo lsof -i :PORT
Process respawns after killCheck if it’s a managed service (launchd, systemd)
“No such process”Process already exited, port should be free
Docker container won’t release portdocker stop then docker rm the container
Kill doesn’t workTry kill -9 (SIGKILL) instead of graceful

Aliases (Optional)

Add to your shell profile:

# What's using this port?
port() { lsof -i :$1; }

# Kill whatever's using this port
killport() { lsof -ti :$1 | xargs kill -9 2>/dev/null && echo "Killed" || echo "Nothing on port $1"; }

# List all listening ports
ports() { lsof -i -P | grep LISTEN; }

  • /pb-doctor - Diagnose system health issues
  • /pb-debug - General debugging methodology
  • /pb-storage - Free disk space when builds fail

Use when: port conflicts, stale dev servers, debugging network issues.