Start MySQL and you get 3306; start PostgreSQL and you get 5432. I usually accept these numbers without a second thought, but one day I started wondering who decided them, and how. Some numbers, like 80 and 443, feel standard. Others, like 3000 and 8080, are the ones you keep running into in local development.

So, using MySQL and PostgreSQL as the entry point, I went digging into the pedigree of port numbers. I covered databases, HTTP, and development servers, relying mainly on official documentation and IANA registration data. It helps a little to think of a port number as a street address, and of IANA as the land registry.

To give away something like a conclusion up front, port numbers come in roughly two types. One is numbers tightly bound to standards and IANA registrations. 80 for HTTP, 443 for HTTPS, 20/21 for FTP, 22 for SSH, and 25 for SMTP fall into this group. For these, the reason the number is used today is relatively clear.

The other is numbers that took root as default settings of products and tools. MySQL's 3306, PostgreSQL's 5432, Tomcat's 8080, 3000 for Rails and Next.js, 5000 for Flask, 8000 for Django, 8888 for Jupyter, and so on. For these, the current default can be confirmed officially, but why that particular number was chosen is often not documented. You can find out who lives there, but not why they picked that address.

How Port Numbers Are Managed

To begin with, port numbers are managed by IANA. RFC 6335 divides them into three broad ranges.

RangeNameWhat it's for
0-1023System PortsStandard services such as HTTP, SSH, and DNS
1024-49151User PortsRange that applications and services register and use
49152-65535Dynamic / Private PortsRange for temporary or private use

On Unix-like operating systems such as Linux, binding to a port below 1024 requires privileges. These are the so-called privileged ports, and the rule has been around for a long time. Given that constraint, it seems entirely natural that high ports have been favored for local development and application servers. Think 8080, 3000, 5000, 8000, and 8888. You can run a server without root.

That said, being registered with IANA and being used by default by some piece of software are two different things. The name on the deed and the person actually living there often don't match. 3000, for example, is a familiar face in web development, but it isn't registered at IANA as a "web development port." Oracle Database's 1521 has long served as the default listener port in Oracle products, yet the IANA registrant isn't Oracle.

Kubernetes API Server's 6443 is the same story. It's commonly used as the default in Kubernetes, but it isn't registered for Kubernetes at IANA. A number can be firmly entrenched in the field and still not match its IANA registrant.

MySQL's 3306

What can be confirmed officially about MySQL is that the default port for the classic MySQL protocol is 3306. MySQL's official documentation treats 3306 as the default. The IANA registry, too, lists 3306 as mysql. Its assignee/contact shows Monty's name. It seems safe to say the registration is tied to Michael "Monty" Widenius, the creator of MySQL.

The crucial question, though, why 3306, is one I couldn't find a clear answer to within the primary sources I checked. The story you often see is that "3306 was chosen because it was the next free number after 3305." Plausible, sure. But at least from the MySQL docs and IANA data I looked at, it's hard to state that explanation as fact.

Here's what I could confirm about MySQL 3306. It is officially MySQL's default. It is registered with IANA as mysql, and Monty's name appears on that registration. Why the number is 3306, however, remains unknown within the scope of this research. That is about as far as it's safe to go.

PostgreSQL's 5432

PostgreSQL, too, has 5432 registered with IANA as the PostgreSQL Database port. Tom Lane's name is in the assignee/contact. Old official PostgreSQL documentation also confirms that default port 5432 was in use from quite early on. At the very least, it's fair to say 5432 took hold early in the history of the PostgreSQL lineage.

Here, too, though, the official archives I checked didn't tell me why it's 5432. PostgreSQL descends from Berkeley POSTGRES. So it's tempting to think the reason for 5432 also dates back to the Berkeley days. But to declare, based only on these sources, that "the meaning of the number 5432 originates at Berkeley" would be a bit reckless.

MySQL 3306 and PostgreSQL 5432 are both numbers that took root as product defaults and are also registered with IANA. The origin of the numbers themselves, on the other hand, is a separate question. That's a territory where primary sources are thin.

Ports for Other Databases

SQL Server's 1433 is described in Microsoft's official documentation as the TCP port used by the default instance. It's also registered with IANA as ms-sql-s 1433. Why 1433, though, is something I couldn't find in the primary sources this time. Oracle Database's 1521 is a slightly different case. Oracle's official documentation describes 1521 as the default port for Oracle Net Listener. It's an extremely well-known number in the field. Look up 1521 at IANA, however, and the registered name isn't Oracle but ncube-lm.

On top of that, IANA carries a note about Oracle's use: "Unauthorized Use Known on port 1521." A standard fixture in the Oracle world, yet hard to call officially registered for Oracle at IANA. It's like a resident who isn't on the deed but has nailed a nameplate to the door and stayed for decades. There's something rather charming about it.

Redis's 6379 and MongoDB's 27017 also have defaults confirmed in official docs. MongoDB's 27017 is registered with IANA as well. But the origins of these numbers, too, weren't clear within the scope of this research.

Elasticsearch is a little more convoluted. Its official documentation describes the default for http.port as 9200-9300 and the default for transport.port as 9300-9400, both as ranges. In conversation we tend to say "Elasticsearch is 9200 and 9300." Strictly speaking, though, it's better to separate the value most likely to be used first from the configured range.

HTTP's 80 and HTTPS's 443

HTTP 80 and HTTPS 443, by contrast, were among the easiest origins to trace of everything I looked at. RFC 1945 indicates that when the port is omitted from an http:// URL, 80 is assumed. The current RFC 9110 also describes the default for http as TCP 80 and for https as TCP 443. These aren't local development conventions; they're numbers fixed by specification.

Is 8080 Just Two 80s?

At IANA, 8080 is registered as http-alt. The description is HTTP Alternate, an alternative port for HTTP. Tomcat also tries to bind to 8080 by default. Its documentation notes that if you change the port, a number above 1024 is preferable. Given the privileged-port restrictions on Unix-like systems, the reason to use a high port like 8080 in place of 80 is easy to understand.

On the other hand, the oft-repeated explanation that "8080 is two 80s side by side" didn't appear in any of the IANA, RFC, or Tomcat primary sources I checked. I get why the number invites that reading. But from primary sources, you can say 8080 is registered as an alternate HTTP port, and no further. You can't claim it became 8080 because someone put two 80s together.

Is 3000 the Web Development Standard?

3000 was the number that left the strongest impression on me during this research. Rails, Express, Create React App, Next.js, Grafana: a great many development tools and applications use 3000. If you do web development, localhost:3000 has become something like a childhood home.

At IANA, however, 3000 is not a web development port. Look it up and you'll find other uses, such as HBCI. It's like checking the deed to your childhood home and finding a stranger's name on it. So 3000 should be seen not as an official web development port but as a de facto standard that took hold in the world of local development.

Rails' old guides use 3000 too, which confirms Rails was using it relatively early. But the sources I checked don't let me go as far as saying Rails is the origin of 3000. Popular projects like Rails used it, and Express and Next.js did too. As a result, the feeling that "web development means 3000" grew stronger. Wouldn't that be the most natural reading?

5000, 8000, 8888, 4200, 5173

Flask uses 5000, Django 8000, Jupyter Notebook 8888, Angular CLI 4200, and Vite 5173 as defaults. All of these current defaults can be confirmed in official docs. The reasons, though, weren't in the official documentation I checked. Why Flask is 5000, why Django is 8000, why Jupyter is 8888: all remain a mystery.

For Vite's 5173 and Angular's 4200, you'll find assorted theories floating around elsewhere. If you limit yourself to what primary sources can confirm, though, there isn't much to say. The current default is confirmed; the reason for the number is unknown. Writing it that way is simply the honest thing to do.

Docker, Kubernetes, Prometheus

For the Docker daemon's remote API, 2375 is described as the conventional port for non-TLS and 2376 for TLS. Docker's documentation uses the word "conventional." It's closer to a Docker operational custom than a number fixed by a standard.

Kubernetes API Server listens on 6443 by default. But at IANA, 6443 isn't Kubernetes; it's sun-sr-https. Once again, the product default and the IANA registered name don't match.

Prometheus uses 9090 as its default. The default is confirmed in official docs. Still, why 9090 is something I couldn't trace within the scope of this research.

Sorting Out the Folklore

Something struck me while researching. With port numbers, "how it's used today" and "why that number was chosen" tend to get jumbled together. Lining up common explanations against what I could confirm gives the following.

Common explanationView within what I researched
HTTP uses 80Confirmed in RFC
HTTPS uses 443Confirmed in RFC
8080 is an alternate HTTP portConfirmed at IANA
8080 is two 80s side by sideNot confirmed in the primary sources this time
MySQL 3306 was the next free number after 3305Not confirmed in the primary sources this time
PostgreSQL 5432 comes from Berkeley and the reason is already explainedUse of 5432 is confirmed, but the reason for the number is not
3000 is an official web development portNot so at IANA; better viewed as a de facto standard
Oracle 1521 is for Oracle at IANA tooThe IANA registrant is not Oracle
Elasticsearch's default is strictly 9200 and 9300Official settings describe it as a range
Kubernetes 6443 is for Kubernetes at IANA tooNot for Kubernetes at IANA

The Full List of Ports

While I'm at it, here's a list of the numbers covered.

PortCommon useView this time
20/21FTPNumber from the standard protocol
22SSHNumber from the standard protocol
25SMTPNumber from the standard protocol
53DNSNumber from the standard protocol
67/68DHCPNumber from the standard protocol
80HTTPDefault specified in RFC
443HTTPSDefault specified in RFC
8080HTTP alternate / TomcatConfirmed as an HTTP alternate port, but the wordplay origin is unconfirmed
3000Rails / Express / Next.js, etc.De facto for web development, but not a web standard at IANA
3306MySQLOfficial default and IANA registration confirmed, reason for the number unconfirmed
5432PostgreSQLOfficial default and IANA registration confirmed, reason for the number unconfirmed
1433SQL ServerOfficial default and IANA registration confirmed, reason for the number unconfirmed
1521Oracle Net ListenerStandard for Oracle, but the IANA registrant is not Oracle
5000FlaskOfficial default confirmed, reason for the number unconfirmed
6379RedisOfficial default confirmed, reason for the number unconfirmed
8000DjangoOfficial default confirmed, reason for the number unconfirmed
8888Jupyter NotebookOfficial default confirmed, reason for the number unconfirmed
1883MQTTStandard MQTT port registered with IANA
8883MQTT over TLSStandard secure MQTT port registered with IANA
2375/2376Docker daemon remote APIConventional Docker ports
27017MongoDBOfficial default and IANA registration confirmed, reason for the number unconfirmed
4200Angular CLIOfficial default confirmed, reason for the number unconfirmed
5173ViteOfficial default confirmed, reason for the number unconfirmed
6443Kubernetes API ServerKubernetes default, but the IANA registrant is for another use
9090PrometheusOfficial default confirmed, reason for the number unconfirmed
9200/9300ElasticsearchStrictly, both HTTP and transport are described as ranges

Defaults That Became Rules

The more familiar a port number is, the more you assume there must be some clear reason behind it. Actually digging in, though, I found surprisingly few whose origins can be traced through primary sources. Some, like HTTP 80 and HTTPS 443, are easy to explain within the standards. Numbers like MySQL 3306, PostgreSQL 5432, 3000, 5000, 4200, and 5173, meanwhile, are used as a matter of course today, yet rarely come with an account of why that number.

This feels very much like the history of software. Something that started as a small default value spreads through users, documentation, sample code, Docker images, cloud configurations and so on. Then, before anyone notices, it's fixed in place as "just the way it is." A number someone typed on a whim may have been copied into configuration files around the world for decades. It's a little amusing to think about.

So when talking about port numbers, separating two things makes everything much clearer. One is that we use this number now; the other is that we know why it was chosen. The nameplate and the deed don't always tell the same story.

That's the story of my look into the origins of common port numbers, starting from MySQL's 3306 and PostgreSQL's 5432. For these two as well, the fact that they're used is clear. But as for the original reason packed into those numbers, at least within what I researched, there was still a blank left. The more ordinary the number, the less its origin gets told.