The one-line answer
localhost is your own machine. When a program on your computer connects to localhost — or to the address it usually resolves to, 127.0.0.1 — it is opening a connection to a server running on that same computer. The traffic goes down the network stack and comes straight back up it, through a virtual network interface called the loopback interface. It never reaches a physical network adapter, never reaches your router, and never reaches the internet. That is the whole idea; everything below follows from it.
127.0.0.1, and the rest of 127.0.0.0/8
127.0.0.1 is the famous one, but it is not special on its own. The entire 127.0.0.0/8 block — every address from 127.0.0.0 through 127.255.255.255, roughly 16.7 million of them — is reserved for loopback. RFC 1122, the 1989 host-requirements standard, spells it out: an address with 127 in the first octet must never appear on a real network, and a host must not send such a packet to any interface other than loopback.
The practical upshot is that 127.0.0.2 and 127.1.2.3 loop back to your own machine too. Most systems let you bind a service to any of them, which is occasionally handy for running two things on the “same” port without a collision — one on 127.0.0.1:8080, another on 127.0.0.2:8080. To the kernel those are genuinely different addresses on the same interface.
Reserving 16.7 million addresses for a job that mostly uses one of them was, in hindsight, extravagant — but it is far too late to reclaim the block now. For the wider picture of how the address space is carved up, start with what an IP address actually is.
The IPv6 loopback: ::1
IPv6 learned from the excess. Instead of an entire /8, it reserves exactly one loopback address: ::1 (that is a /128, the compressed form of 0000:0000:0000:0000:0000:0000:0000:0001). It behaves identically — packets addressed to ::1 loop back inside the host and must never be forwarded. If the compressed notation looks like line noise, the IPv6 address format guide explains the colon-and-double-colon rules.
How the loopback interface actually works
Your machine has a virtual network interface — lo on Linux, lo0 on macOS and BSD, an internal loopback adapter on Windows. To the kernel it is a real interface: it has an address and an MTU, and it shows up in ip addr or ifconfig. What it does not have is any hardware behind it.
When your browser opens a TCP connection to 127.0.0.1:3000, the kernel builds the packet, consults its routing table, sees the destination belongs to the loopback interface, and hands the packet back to its own receive path instead of putting it on a wire. No Ethernet frame, no ARP, no Wi-Fi radio, no NIC driver, no switch, no router.
Two things follow, and they are why developers live on it:
- It works with nothing plugged in. No cable, no Wi-Fi, no DHCP lease, no ISP. Your dev server keeps serving in airplane mode.
- It is fast. No physical medium, no propagation delay, no contention — loopback throughput is bounded by memory bandwidth and CPU rather than by a link. Packets still traverse the TCP/IP stack, so it is not free, but next to a real network it may as well be.
“localhost” is a hostname, not an address
This distinction trips people up constantly. 127.0.0.1 is an IP address; localhost is a hostname — a name that must be resolved to an address first, exactly like example.com. The difference is where the answer comes from. localhost is almost never resolved by DNS; it is resolved by your hosts file, a plain-text lookup table the OS consults before it ever asks a DNS server:
- Linux and macOS:
/etc/hosts - Windows:
C:\Windows\System32\drivers\etc\hosts
Open it and you will find, near the top, something very close to these two lines:
127.0.0.1 localhost
::1 localhostThat is the whole mechanism: localhost works because a file on your disk says it points at the loopback addresses. Nothing is queried over the network. (Some systems also special-case the name in the resolver library so it survives a mangled file, but the hosts file is where it is canonically defined — and the first place to look when it misbehaves.) The same file lets you point any other name at loopback: add 127.0.0.1 myapp.local and http://myapp.local:3000 reaches your dev server.
Why developers live on localhost
Run a Next.js dev server and it tells you it is ready on http://localhost:3000. Rails picks 3000 too, Django 8000, Vite 5173. In every case a server process listens on a port on the loopback interface and your browser — another process on the same machine — connects to it. The whole request/response cycle happens inside your laptop.
The same pattern runs through infrastructure. A well-configured PostgreSQL, MySQL, or Redis instance on a single-server deployment binds to 127.0.0.1, so only the application running beside it on that host can reach it. The common ports reference lists which service conventionally sits on which number.
The security point: 127.0.0.1 vs 0.0.0.0
This is the part worth internalising, because getting it wrong is how databases end up on the public internet. When a server starts it binds to an address and a port, and the address it binds to decides who can reach it:
- Bind to
127.0.0.1and the socket is attached to the loopback interface only, reachable exclusively by processes on that same machine. A packet arriving from your LAN or the internet cannot be delivered to it, because it is not listening on the interface those packets arrive on. That is a property of the socket itself, not a firewall rule you can forget to apply. - Bind to
0.0.0.0and you have said “listen on every IPv4 address this host has” — loopback, your LAN address, your VPN interface, and on a cloud VM the public address. Anyone who can route a packet to that machine on that port can attempt to connect. (The IPv6 wildcard is::.)
0.0.0.0 is not an address you connect to; it is a wildcard you listen on. That framing clears up a lot of confusion.
So: a Redis instance bound to 127.0.0.1:6379 is fine. The same Redis bound to 0.0.0.0:6379 on a cloud VM with a permissive security group is an unauthenticated key-value store on the open internet, and it will be found — scanners sweep the entire IPv4 space continuously. Bind to loopback unless you have a specific reason not to, and when you must listen more broadly, add authentication and a firewall rule in the same change. To check what is genuinely exposed, the port checker tries to reach a port on your public IP from the internet side.
localhost vs your private IP vs your public IP
Three different addresses, three different scopes. People conflate them constantly:
- Loopback —
127.0.0.1/::1. Scope: this machine. Every computer in the world has one, and they do not conflict, because they are not on a network. - Private LAN IP — typically
192.168.x.x,10.x.x.x, or172.16–31.x.x. Scope: your local network. Your router hands it out; your phone, laptop, and printer reach each other on it. Not routable on the public internet — see public vs private IP. - Public IP. Scope: the internet. The address your ISP assigns your router, and the one every website you visit actually sees. Check yours with what is my IP.
A concrete example: a dev server bound to 127.0.0.1:3000 is invisible to your phone on the same Wi-Fi. To test on the phone you would bind to 0.0.0.0:3000 and visit your laptop's private LAN IP — http://192.168.1.42:3000, say. Your public IP still would not reach it without deliberate port forwarding.
Common gotchas
The 127.0.0.1 vs ::1 mismatch
The classic. Your hosts file maps localhost to both 127.0.0.1 and ::1, but your server binds only to IPv4 127.0.0.1. The client resolves localhost, gets ::1 first (many runtimes prefer IPv6), tries it, and gets connection refused — even though the server is plainly running. The tell-tale symptom is that http://127.0.0.1:3000 works while http://localhost:3000 does not, or the reverse. Fix it by binding the server to both stacks, or by using the literal address that works.
Firewall confusion
People routinely open a firewall port to fix a connection that was never going to work, because the service was bound to loopback all along — and no firewall change will ever make a loopback-bound socket reachable from another machine. Check the bind address before you touch any rules: ss -tlnp on Linux, netstat -an on macOS or Windows. If the local address column shows 127.0.0.1:PORT, the bind is your problem. If it shows 0.0.0.0:PORT, only the firewall stands between that service and the network.
Frequently asked questions
Is 127.0.0.1 the same as localhost?
Almost, but not quite. 127.0.0.1 is an address; localhost is a hostname that conventionally resolves to it. In a typical hosts file localhost maps to both 127.0.0.1 and ::1, so a program asking for localhost may get either — which is exactly why a server listening only on 127.0.0.1 can look unreachable at localhost if the client tries ::1 first.
What is the difference between binding to 127.0.0.1 and binding to 0.0.0.0?
Binding to 127.0.0.1 attaches the service to the loopback interface only, so only processes on the same machine can reach it. Binding to 0.0.0.0 means “all IPv4 interfaces on this host”, so it also answers on your LAN IP and every other interface — anyone who can route packets to that machine can attempt to connect. Use 127.0.0.1 for databases, admin panels, and dev servers that only your own machine needs; reach for 0.0.0.0 only when you deliberately want other machines to connect, with authentication and a firewall in front of it.
Does localhost work without an internet connection?
Yes. Loopback traffic never leaves the machine — it does not touch your Ethernet or Wi-Fi adapter, your router, or your ISP. That is why a dev server at localhost:3000 keeps working on a plane with no Wi-Fi, no cable plugged in, and no DHCP lease.
Related reading
- What is an IP address? — the ground floor: how addresses are structured and which ranges are reserved.
- Public vs private IP — the difference between the address your router gives you and the one the internet sees.
- What is my IP? — see the public address the rest of the world actually connects to.
- Common ports — which service conventionally lives on which port number.
- Port checker — test from the outside whether a port on your public IP is genuinely open.
- IPv6 address format — how
::1and its longer cousins are written and compressed. - Networking glossary — short definitions for everything above.
