3306 MySQL TCP Flagship
Reference for TCP port 3306, commonly associated with MySQL.
What it's for
Port 3306 is the default port for MySQL (and its widely used fork, MariaDB) — one of the most deployed relational database systems in the world. Application servers connect to port 3306 to run queries, and it's the port you'll configure in nearly every framework's database connection string when using MySQL as the backend.
Because it's so ubiquitous in web application stacks (the "M" in the classic LAMP stack), port 3306 shows up constantly in local development (127.0.0.1:3306), Docker Compose files, and managed database service connection strings (AWS RDS, Google Cloud SQL, PlanetScale, etc.).
Protocol basics
- Protocol: TCP, since database connections need reliable, ordered delivery of queries and results.
- Binary wire protocol. MySQL's client-server protocol is a custom binary format, not a text protocol like HTTP — this is why you need a proper MySQL client or driver rather than something like
curlto talk to it meaningfully. - Persistent connections are the norm. Applications typically open a connection (or a pool of connections) to port 3306 and reuse it across many queries, rather than opening a new TCP connection per query, for performance reasons.
- TLS support is optional but recommended. MySQL supports encrypting the connection, but unlike HTTPS on the web, it's not always enabled by default depending on server and client configuration.
Security considerations
- Port 3306 should almost never be exposed to the public internet. Database ports are a prime target for credential-stuffing and exploitation attempts; the standard architecture keeps MySQL reachable only from application servers on a private network or VPC, never directly from
0.0.0.0/0. - Use strong, unique credentials and avoid the default root account for application connections — create scoped users with only the privileges the application actually needs (principle of least privilege).
- Enable TLS for connections that cross any untrusted network boundary, including connections to managed cloud database services over the public internet.
- Restrict by IP/security group whenever possible, layering network-level access control on top of database authentication rather than relying on credentials alone.
Troubleshooting
"Can't connect to MySQL server on 'host' (10061)" / connection refused:
- MySQL isn't running, or is bound only to
localhost/127.0.0.1rather than listening on the network interface you're connecting from — check thebind-addresssetting inmy.cnf
"Host is not allowed to connect to this MySQL server":
- The connecting host's IP isn't authorized for that MySQL user — MySQL user permissions are tied to both username and the allowed host/IP pattern
Connects locally but not from another server/container:
- Classic Docker/networking issue — confirm the container is exposing/publishing port 3306 correctly, and that
bind-addressisn't restricted to127.0.0.1inside the container
"Too many connections" errors:
- The connection pool size in your application (or the aggregate across multiple app instances) is exceeding MySQL's
max_connectionssetting — either raise the limit or reduce pool size/add connection pooling middleware
Comparison / FAQ
| Port | Protocol | Key difference from 3306 (MySQL) |
|---|---|---|
| 5432 (PostgreSQL) | TCP | Different relational database engine with its own wire protocol; broadly similar deployment patterns |
| 1433 (MSSQL) | TCP | Microsoft SQL Server's default port, common in Windows-centric enterprise stacks |
| 6379 (Redis) | TCP | In-memory key-value store rather than a full relational database, used for caching/sessions more than persistent structured data |
Is it safe to expose port 3306 to the internet for a managed cloud database?
Even for managed databases, best practice is to restrict access via VPC/security group rules and require TLS, rather than allowing open internet access on the port itself — most managed providers support this natively and it should be treated as the default, not an optional hardening step.
Why does my app work locally but fail to connect to MySQL in Docker?
Almost always a networking/binding issue — confirm the MySQL container's port is actually published (-p 3306:3306 or the Compose equivalent) and that the app is connecting to the correct hostname (the Docker service name, not localhost, when connecting between containers).
What's the difference between MySQL and MariaDB in terms of the port?
They both default to port 3306 and are wire-protocol compatible in the vast majority of cases, since MariaDB began as a fork of MySQL — most clients and drivers work interchangeably against either.
Can I run multiple MySQL instances on the same server?
Yes, but each instance needs its own distinct port (or you'd have a conflict), typically configured via the port setting in each instance's configuration file — a common pattern in local development with multiple project databases.