Common Ports Explained: A Working Reference for Port Numbers
A practical guide to common ports and port numbers: 22, 80, 443, 3306, 5432 and more, plus well-known vs registered ranges and how to troubleshoot a port that won't connect.
Common Ports Explained: A Working Reference for Port Numbers
A port number is just a 16-bit label that tells the operating system which program should receive an incoming packet. There are 65,536 of them, but in day-to-day work you keep meeting the same two dozen. Knowing those cold is the difference between writing a firewall rule in ten seconds and grepping through three browser tabs while a deploy stalls.
This guide covers the port numbers you actually run into, how the IANA ranges carve up the space, and a repeatable way to figure out why a port is not answering.
The ports you meet every day
Most of a developer's life happens on a short list. HTTP is 80, HTTPS is 443. SSH is 22, which is why ssh user@host needs no port flag. DNS is 53, SMTP is 25 for server-to-server mail and 587 for client submission. On the database side: MySQL and MariaDB default to 3306, PostgreSQL to 5432, Microsoft SQL Server to 1433, Redis to 6379, MongoDB to 27017, and Elasticsearch exposes its REST API on 9200. Windows Remote Desktop sits on 3389, and the eternal "alternate HTTP" proxy port is 8080.
You do not need to memorise the full list to work fast — you need a place to look it up that filters instantly. The Common Ports Reference is a searchable table of 60+ services: type a number like 3306 or a keyword like redis and the matching row appears with the protocol, a plain-language note, and the range it belongs to. Because it is a static table baked into the page, there is no upload and no API call; your search term rides in the URL so a filtered view is shareable with a teammate.
Well-known vs registered vs dynamic
IANA, the body that hands out port assignments, splits the 16-bit space into three bands. This is the single most useful piece of structure to carry in your head:
- Well-known (system) ports: 0–1023. The classics live here — 22, 25, 53, 80, 443. On Unix-like systems, binding to a port in this range historically requires root or an explicit capability, which is a security feature: a random user process cannot impersonate your web server on 443.
- Registered (user) ports: 1024–49151. Assigned to specific applications but bindable by any ordinary user. MySQL's 3306, PostgreSQL's 5432, and the 8080 proxy port all live here.
- Dynamic, private, or ephemeral ports: 49152–65535. The OS hands these out to the client side of an outbound connection. When your browser opens a connection to a server on 443, your own end is some ephemeral port the kernel picked. WireGuard's default 51820 also sits in this band.
A common off-by-one trips people: well-known ports end at 1023, not 1024. Port 1024 is the first registered port. That boundary shows up on certification exams and whenever you reason about which ports need elevated privileges to bind.
TCP and UDP are separate spaces
One detail surprises people more than it should: TCP port 53 and UDP port 53 are different slots. TCP and UDP are independent address spaces, so the same number can host different things on each. TCP is connection-oriented and reliable — SSH, HTTPS, and database protocols use it because every byte must arrive in order. UDP is connectionless and lightweight — DNS queries, NTP time sync, DHCP, and game traffic use it because speed beats guaranteed delivery.
Some services use both. DNS answers small queries over UDP and falls back to TCP for large responses and zone transfers, which is why a good reference marks its row TCP/UDP rather than picking one. If you want to go deeper on what those DNS records actually carry once you are on 53, the DNS Record Explainer breaks down A, AAAA, MX, TXT, and the rest in the same plain-language style.
Troubleshooting: why won't this port connect?
Here is the loop I run, in order, almost on reflex when a service is unreachable. A real example: last month a colleague's app could not reach Postgres from a new container, and "the database is down" was the working theory. It was not.
- Is something actually listening? On the database host I ran
ss -tulpn | grep 5432. Postgres was bound — but only to127.0.0.1, not0.0.0.0. That alone explained the failure: a process listening on localhost is invisible to every other machine. - Is the right port even the one you think? Cross-check the number against a reference before assuming. A log line showing traffic to
11211is Memcached, not your app;6379is Redis. Reading the wrong port as "the service" sends you debugging in the wrong place entirely. - Is a firewall or security group in the way? Cloud security groups silently drop packets to ports you never opened. Confirm the inbound rule names the exact port and a tight source range.
- What does the live system say vs. what should be there? A reference tells you the conventional purpose of a port; it never scans your machine. The live commands —
ss -tulpnorsudo lsof -i :5432on Linux/macOS,netstat -anoplustaskliston Windows — tell you what is actually bound. When those two disagree, that gap is your bug.
In the Postgres case the fix was one line in postgresql.conf (listen_addresses = '*') plus a security-group rule scoped to the app subnet — not 0.0.0.0/0. Which leads to the one rule worth tattooing on the inside of your eyelids: database and cache ports (3306, 5432, 6379, 27017) should bind to localhost or a private network, never the open internet. Exposed, unauthenticated Redis and MongoDB instances have caused famous mass-ransom incidents. A firewall rule on those ports is not optional.
A few habits worth keeping
Label every published port in your docker-compose.yml or Kubernetes manifest with the real default — Kafka 9092, RabbitMQ 5672 plus its 15672 management UI, Elasticsearch 9200 — so nothing collides and the next reader is not guessing. When you scope a firewall rule, open exactly the ports the app needs and no more. And when you hit an unfamiliar number, look it up before you act on a guess.
For the adjacent pieces of the same puzzle, the IP Subnet Calculator handles the CIDR ranges you point those firewall rules at, and the HTTP Status Explorer decodes what comes back once a connection on 80 or 443 actually succeeds. Keep all three within reach and most "it won't connect" mysteries resolve in a couple of minutes.
Made by Toolora · Updated 2026-06-13