What’s running on port 3001 on my Mac?
Nobody picks 3001 on purpose for long. It’s usually a sign that something already held 3000, or a backend sitting next to a frontend. Here’s how to tell which.
Updated
Commonly used by
- Next.js (fallback)When 3000 is busy, recent
next devversions move to 3001, 3002 and so on. - Create React App (fallback)
react-scripts startasks “Would you like to run the app on another port instead?” and picks 3001. - Backend APIsA common convention: frontend on 3000, Express/NestJS/Rails API on 3001.
- Uptime KumaThe self-hosted monitor serves its dashboard on 3001.
Check what’s on port 3001
lsof -nP -iTCP:3001 -sTCP:LISTEN
Then check the neighbors, because 3001 rarely shows up alone:
lsof -nP -iTCP:3000-3005 -sTCP:LISTEN
lsof accepts a port range, so this one line shows the whole stack of fallback servers. If you see two node processes, compare their folders to find the duplicate:
lsof -a -p <PID> -d cwd -Fn | tail -1
With Stat Space: statspace port 3001.
The fallback trap
A server on 3001 that you didn’t ask for usually means the one on 3000 is a leftover: a dev server from yesterday, one started by an editor task, or one an AI coding agent launched and never stopped. The new one works, so you don’t notice, until a login redirect sends you to localhost:3000 and you’re suddenly looking at old code.
The fix is to stop the stale one and pin your port:
kill <PID-on-3000>
next dev -p 3000
If the parent of the old process is 1 (launchd), its terminal is gone. Finding orphaned Node processes covers sweeping them all at once.
Running an API on 3001 deliberately
If 3001 is your backend, set it explicitly so it never collides with a fallback frontend:
| Tool | Set the port |
|---|---|
| Express / Fastify | PORT=3001 node server.js and read process.env.PORT |
| NestJS | await app.listen(process.env.PORT ?? 3001) in main.ts |
| Rails API | bin/rails server -p 3001 |
| Uptime Kuma | UPTIME_KUMA_PORT=3002 or change the Docker -p mapping |
If the frontend falls back to 3001 while your API is already there, the frontend moves on to 3002 and your API calls still work. But if the API starts second, it fails with EADDRINUSE. See address already in use.
Seeing it live
Stat Space shows 3000, 3001 and 3002 side by side with each project folder and uptime, so a duplicate copy of the same project is obvious. Each row says who started it, and you can stop the stale one from there.
Questions
Why did my app start on 3001 instead of 3000?
Something was already listening on 3000, often an older copy of the same project. Run lsof -nP -iTCP:3000 -sTCP:LISTEN to find it. Stop it if it's stale, then restart your server to get 3000 back.
How do I stop Next.js from switching ports automatically?
Pass the port explicitly, for example next dev -p 3000. If 3000 is taken you'll get an error instead of a silent move, which makes leftover servers easier to notice.
Is it a problem if I have servers on 3000, 3001 and 3002?
Each one uses memory and CPU, and your browser tab may be talking to an old build. It also breaks OAuth callbacks and CORS rules that expect a specific port. Clean up the ones you don't need.
Know what your Mac is doing, without adding to it.
Free, no account. Pro is $9.99 once for the first 100 buyers.