To send a letter you need two things: the address of the building, and the number of the apartment inside it. Computers on a network work exactly the same way. The IP address finds the right computer, and the port finds the right program running on it. Once you see that, things like 127.0.0.1:3000 or "port 5432 is already in use" stop being mysterious.
A network is just a bunch of computers that can send each other messages. The internet is the biggest one. The messages travel in small chunks called packets, and every packet carries a label saying where it's going, a bit like the front of an envelope.
That label has two parts:
When you write them together, a colon separates them: address:port. You've probably seen this in a browser already, as in http://localhost:3000.
The most common kind of IP address is IPv4 (version 4 of the Internet Protocol). It's written as four numbers separated by dots, like 192.168.1.23. Each of the four numbers is called an octet, and each must be between 0 and 255.
Why 255? Because under the hood each octet is stored in 8 bits (8 ones-and-zeros), and the biggest number 8 bits can hold is 11111111 in binary, which is 255. Four octets make 32 bits in total, so there are 232 = 4,294,967,296 possible IPv4 addresses. That sounded like plenty in the 1980s. It isn't today, and we'll see the trick that keeps the internet working anyway.
Type any address below. The checker tells you whether it's valid, what kind of address it is, and shows the 32 bits hiding behind the dots.
IPv4 checker
A few things worth noticing as you play: 256 anywhere makes the address invalid, so does a missing or extra octet, and the checker rejects octets with leading zeros like 010. That last one is a real trap: some older software reads a leading zero as an octal (base-8) number, so 010 would mean 8, not 10. Modern tools such as Python's ipaddress module simply refuse it.
Not every address works everywhere. The ones you'll meet most often fall into three groups.
A public address is unique across the whole internet, like a real street address. Anyone, anywhere, can send packets to it. Websites, mail servers and your home router's outside face all have public addresses. They're handed out by internet providers and can't simply be made up.
Since there aren't enough IPv4 addresses for every phone, laptop and smart lightbulb, three blocks were set aside as private (the rule is written down in a standard called RFC 1918). Any home or office can use them, so millions of networks reuse the very same numbers, the way millions of buildings all have an "apartment 2".
| Private range | Where you'll see it |
|---|---|
| 10.0.0.0 – 10.255.255.255 | Big offices, company networks, cloud setups |
| 172.16.0.0 – 172.31.255.255 | Docker's default networks, AWS's default cloud network. Note: only 16 to 31 in the 2nd octet |
| 192.168.0.0 – 192.168.255.255 | Almost every home Wi-Fi router |
Packets addressed to a private address are never routed across the public internet. So how does your laptop at 192.168.1.23 load a website? Your router does a trick called NAT (Network Address Translation): it swaps your private address for its own single public address on the way out, remembers who asked, and swaps it back when the reply arrives. The whole house shares one public address, like an apartment block with one street address and a mailroom that sorts letters to the right door.
Every computer has a special address that means "me, this very machine": 127.0.0.1. Packets sent there never leave the computer; they loop straight back in, which is why it's called the loopback address. The name localhost is set up to point to it. (In fact the whole block 127.0.0.0 to 127.255.255.255 is loopback, but 127.0.0.1 is the one everybody uses.)
This is the address you'll use most as a developer. When you run a website on your own laptop while building it, you visit http://localhost:3000: "talk to the program on this computer, on port 3000". The key point: 127.0.0.1 means a different machine depending on who says it. If you tell a friend "go to 127.0.0.1:3000", they'll reach their own computer, not yours.
What about IPv6? The newer IPv6 uses 128-bit addresses written in hexadecimal with colons, like 2001:db8::1. There are so many that running out isn't a concern. Its loopback address is ::1. Both versions run side by side today; everything about ports in this article works the same for both.
A port is a whole number from 0 to 65535 (it's stored in 16 bits, and 216 = 65,536). A program that wants to receive network traffic asks the operating system: "please send me everything that arrives on port 5432". This is called listening on a port, or binding to it. From then on the OS delivers matching packets to that program.
Some port numbers are used by convention so that nobody has to ask "which door?". Ports below 1024 are called well-known ports, and on Linux a normal program needs admin rights to listen on them.
| Port | Who usually lives there |
|---|---|
| 22 | SSH, the secure shell, used to log in to a remote server and type commands on it |
| 80 | HTTP, plain (unencrypted) web pages |
| 443 | HTTPS, encrypted web pages: the padlock in your browser |
| 5432 | PostgreSQL, a popular database (MySQL's default is 3306) |
| 3000 | No official owner. It's just a developer habit: Rails, many Node.js tutorials and other tools pick it for local development servers. 8000 and 8080 are similar habits |
You usually don't type the port for websites because the browser fills it in: http:// means port 80 and https:// means port 443 unless you say otherwise. So https://example.com is really https://example.com:443. When a server uses a non-standard port, you have to write it, which is why development addresses look like http://localhost:3000.
Below is a server at 203.0.113.10 (an address reserved for examples, so it's safe to use in docs) with five "apartments". Choose where your packet starts, which address and which port it goes to, and send it. Watch the envelope: it has a from address and port as well as a to, because the reply needs to find its way back.
Packet delivery simulator
Things to try: send to port 8080 (nobody lives there), send to 5432 from your laptop, then from inside the server to 127.0.0.1, and send to 127.0.0.1 from your laptop. Then press "Start a 2nd app on port 3000".
Two lessons hide in there. First, a program can choose which addresses it listens on. PostgreSQL, out of the box, listens only on localhost, so other computers can't reach it even if they know the port. That's a safety feature: a database usually should only be talked to by programs on the same machine (or a private network). Many development servers do the same.
Second, only one program can listen on a given port (on the same address) at a time. It's one apartment, one tenant. If you start your dev server twice, the second one fails. In Node.js the error contains EADDRINUSE: address already in use; in Python on Linux it's OSError: [Errno 98] Address already in use. The fix is to stop the first program, or start the second on a different port.
Put it together and the picture is simple. A single server with one IP address can run a web server on 443, SSH on 22 and a database on 5432 all at once, because the operating system keeps a little table: port 22 → sshd, port 443 → nginx, port 5432 → postgres. Every incoming packet is looked up in that table and handed to the right program. A packet for a port with no listener gets turned away; the sender sees a "connection refused" error.
Your laptop does the same on the other side. When your browser opens a connection, the OS gives it a temporary high-numbered port (something like 52114), called an ephemeral port. That's the "from" apartment on the envelope, so the reply comes back to the right browser tab. Because each connection is identified by all four numbers together (from-address, from-port, to-address, to-port), thousands of people can talk to the same :443 at the same moment without their replies getting mixed up.
You can try this yourself. If you have Python installed, open a terminal and run:
python3 -m http.server 8000
That starts a tiny web server sharing the current folder on port 8000. Visit http://localhost:8000 in your browser and you'll see your files. Open a second terminal and run the same command again: you'll get the "Address already in use" error. Run it with 8001 instead and both servers happily share the same computer. Press Ctrl+C to stop them.
Which of these is a valid IPv4 address?
172.31.0.5 has four octets, all between 0 and 255 (it's private, too). 10.0.300.1 has 300, which doesn't fit in 8 bits, and 192.168.1 has only three parts.
You're building a site and it runs at http://127.0.0.1:3000. You send that link to a friend. What happens when they open it?
127.0.0.1 always means "this machine", from the point of view of whoever uses it. Unless your friend is also running something on port 3000, they'll get "connection refused".
You visit https://example.com without typing a port. Which port does your browser connect to?
https:// defaults to port 443. Plain http:// defaults to 80. 3000 is only a developer habit and is never filled in automatically.
Your dev server won't start and says address already in use. What's the most likely cause?
One port, one listener. Often it's a copy of the same server you forgot to stop in another terminal. Stop it, or pick a different port.
address:port.10.x, 172.16–31.x, 192.168.x) are reused in every home and office; routers use NAT to share one public address.127.0.0.1 / localhost always means "this same machine".Next time you see localhost:5432 in a config file, you can read it out loud: "the database on this very machine, apartment 5432".