DEV Community

Cover image for What's using port 3000 on my Mac? Find it, see who started it, and stop it safely
Tj Thouhid
Tj Thouhid

Posted on

What's using port 3000 on my Mac? Find it, see who started it, and stop it safely

You run npm run dev and get this:

Error: listen EADDRINUSE: address already in use :::3000
Enter fullscreen mode Exit fullscreen mode

The usual advice is "find the PID and kill it". That works, but it skips the questions that actually matter. What is on port 3000? Which project does it belong to? Did I start it, did my editor, or did an AI agent start it in the background an hour ago? And is it safe to stop?

Here's how to answer all of that on macOS with commands that are already installed. After that, I'll show how I do the same thing in a Mac app I build.

1. A quick look

lsof -i :3000
Enter fullscreen mode Exit fullscreen mode

On macOS, plain lsof -i :3000 may print a service name such as hbci instead of 3000; step 2 fixes that.

This lists every process with a network connection on port 3000. That includes the server, but also your browser tabs that are connected to it, so the list can be longer than you expect.

2. Just the thing that's listening

lsof -nP -iTCP:3000 -sTCP:LISTEN
Enter fullscreen mode Exit fullscreen mode
  • -iTCP:3000 limits it to TCP on port 3000.
  • -sTCP:LISTEN shows only the process that's listening, which is the one holding the port.
  • -n and -P skip name lookups. It's faster, and you see 3000 rather than a service name.

You'll get something like:

COMMAND   PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
node    48213 tj     23u  IPv6  0x...       0t0  TCP *:3000 (LISTEN)
Enter fullscreen mode Exit fullscreen mode

You might see two lines, one for IPv4 and one for IPv6. They can even be two different processes. That's how you get the confusing case where the browser shows an old version of your app while your terminal says the new one started fine.

3. What is it, who owns it, and for how long?

Take the PID and ask ps:

ps -p 48213 -o pid,ppid,user,etime,command
Enter fullscreen mode Exit fullscreen mode
  PID  PPID USER  ELAPSED COMMAND
48213 48190 tj   01:12:40 node /Users/tj/code/shop/node_modules/.bin/vite
Enter fullscreen mode Exit fullscreen mode
  • command is the full command line. It often includes the project path (/Users/tj/code/shop here), which is usually the quickest way to tell which project it belongs to.
  • etime (shown as ELAPSED) is how long it's been running. An hour and twelve minutes means this isn't the server you just tried to start.
  • user is who owns it. If it isn't you, see step 4.
  • ppid is the parent process. Run the same command on it to see what launched it:
ps -p 48190 -o pid,ppid,user,etime,command
Enter fullscreen mode Exit fullscreen mode

Keep going up and you'll usually hit zsh and then Terminal, an editor's helper process (VS Code, for example), or an AI tool's shell. If the PPID is 1, the original parent has exited and macOS's launchd adopted the process. That's typical for a server left running in the background after the thing that started it went away.

4. Nothing shows up? It may belong to another user

lsof only lists your own processes unless you run it with sudo:

sudo lsof -nP -iTCP:3000 -sTCP:LISTEN
Enter fullscreen mode Exit fullscreen mode

If the port is held by a process owned by root or another user, this is how you'll see it.

5. Stop it, gently first

kill 48213
Enter fullscreen mode Exit fullscreen mode

kill sends a polite "please quit" signal (SIGTERM), so the program can shut down properly. Give it a couple of seconds and run the lsof command from step 2 again. Only if it's still there:

kill -9 48213
Enter fullscreen mode Exit fullscreen mode

kill -9 ends it immediately, with no chance to clean up. Use it as the second step, not the first.

A few things to watch for:

  • Another user's process. You'll get "Operation not permitted". You'd need sudo kill 48213, so first be sure it's really something you mean to stop.
  • Still busy after you stopped it? Dev servers often start child processes. Run step 2 again and see what's listening now.
  • It comes straight back? Something is restarting it, such as a service manager, Docker, or an app like Laravel Herd. Stop it there instead of killing it again.
  • Ports 5000 and 7000. On recent macOS versions, AirPlay Receiver listens on these. If a Flask app can't get port 5000, that's probably why. Pick another port, or turn AirPlay Receiver off in System Settings.

The same thing in Lokstack

Disclosure: I build Lokstack, and this part is about my own app.

I built Lokstack partly because I got tired of running these commands one after another. It's a free Mac app, and everything in this section is on the free plan.

Ports page. Search for 3000. Lokstack shows which program holds the port, which project it belongs to, who started it, and how long it's been up. There are two buttons. Stop asks the program to quit, like kill. Kill is the force option, like kill -9.

Lokstack Ports page: a listening port with the program, project, who started it, uptime, and Stop and Kill buttons

"Why won't it start?" on a project's Overview. If the project has a saved port and something else is using it, a red box says "Port 3000 is already taken" with a Free port 3000 button. That's the one-click version.

Run & logs. If the app you start prints EADDRINUSE or "address already in use", Lokstack explains it in plain words and offers the same fix.

What it won't do, so you know where the edges are:

  • Databases and services are protected. Lokstack won't stop them by accident.
  • Programs owned by another user (for example a server running as root) can't be stopped from Lokstack. It says "Permission denied", and in Terminal you'd need sudo.
  • Laravel Herd sites are stopped by asking Herd to stop all its services, not by killing that one process.
  • The Free port button only appears for projects with a saved port. Stop and Kill on the Ports page always work.

Wrapping up

When you see EADDRINUSE, find out what's actually listening, check what it is and who owns it, and stop it gently before you force it. If it keeps coming back, stop it where it's managed (Docker, a service manager, Herd) instead.


Lokstack is a free Mac app that shows what is using a port, which project it belongs to and who started it, and lets you stop it in one click. It won't touch your databases by accident. If you'd rather stay in Terminal, the commands above are all you need. https://lokstack.app

What's the strangest thing you've found holding a port? I'd like to hear it in the comments.

Top comments (0)