Your computer can run many local services at once.
A browser can talk to a React app. A backend can talk to a database. A command line tool can talk to Ollama. All of this can happen on the same machine because each service uses a different port.
A port is a numbered door.
localhost:3000 -> usually a frontend dev server
localhost:8000 -> often a backend API
localhost:6379 -> often Redis
localhost:11434 -> often Ollama
The number after the colon tells your operating system which door to knock on.
The mental model
If localhost is the building, the port is the door.
http://localhost:3000
means:
Go to this machine and knock on door 3000.
This:
http://localhost:8000
means:
Same machine, different door.
The browser can reach the building, but it still needs the correct door.
One door, one listener
For a given address and protocol, only one process can listen on the same port at the same time.
That is why dev tools sometimes show errors like:
EADDRINUSE: address already in use
Port 3000 is already in use
bind: address already in use
It means another process already owns that door.
You have two choices:
- Stop the process that owns the port.
- Start your new process on a different port.
Both can be correct. The important thing is to know which one you are doing.
Common local ports
These are not universal rules, but they are common enough to be worth remembering:
| Port | Often used by |
|---|---|
3000 | React, Next.js, frontend dev servers |
5173 | Vite |
5432 | PostgreSQL |
6379 | Redis |
8000 | Django, FastAPI, Python servers |
8080 | Java apps, proxies, alternate HTTP servers |
11434 | Ollama |
A port number alone does not prove what the process is. It is only a clue.
Find who owns a port
On macOS, use:
lsof -nP -iTCP:3000 -sTCP:LISTEN
Example output:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 48217 you 21u IPv4 ... TCP 127.0.0.1:3000 (LISTEN)
Read it like this:
COMMANDis the process name.PIDis the process ID.NAMEshows the address and port.(LISTEN)means it is waiting for connections.
Check whether a door is open
You can test a port without opening a browser:
nc -vz 127.0.0.1 3000
If something is listening, you will see a successful connection message. If not, you will get a refusal or timeout.
You can also use curl for HTTP services:
curl http://127.0.0.1:3000
curl is useful because it shows the raw response, not the browser’s interpretation.
The difference between a port and a URL path
These are different things:
http://localhost:3000/pricing
localhostis the host.3000is the port./pricingis the path inside the application.
If no process is listening on 3000, the path does not matter. The request never reaches the app.