The PostgreSQL default port is 5432 — a TCP port hard-coded into the libpq client library and the postgres server binary at compile time, and a port that almost every Postgres installation in the world listens on unless an admin has explicitly changed it. The number is not magic, the number is a deliberate IANA assignment for postgresql, and the number is the one every connection string, every Docker port mapping, and every firewall rule references by default. The interesting part is why 5432 (not 5433, not 3306), how to verify the port on any server, how to change it without breaking the seven clients that depend on it, and the five other ports in the Postgres ecosystem (5433, 5434, the pg_ctl debug port, the WAL receiver, the replication port) a developer ends up caring about.
The reason “postgresql default port” is its own question and not just “what port is Postgres” is that the port is the most common answer a developer needs when they are debugging a connection refused error, when they are wiring up a Docker port mapping, when they are configuring a firewall, or when they are reading a connection string. The port is the single most common thing to get right and the single most common thing to get wrong, and the port is the lever that turns “I cannot connect” into “I am connected.”
Table of contents
- The short version
- Why 5432, not 3306, not 5433
- How to verify the port on any Postgres server
- How to change the port without breaking clients
- The five other ports in the Postgres ecosystem
- The seven gotchas when wiring up 5432 in production
- The way Docker and managed services handle 5432
- FAQ
The short version
Postgres listens on TCP 5432 by default. The port is compiled into the postgres server binary and into every libpq-based client (psql, pg_dump, pg_dumpall, pg_restore, vacuumdb, reindexdb, createdb, dropdb, createuser, dropuser, pg_isready, clusterdb). The port is also the one the IANA has assigned to the postgresql service name (registered 2010, replacing the older pg and postgresql-1 aliases). The port is overridable via the port parameter in postgresql.conf, via the PGPORT environment variable for clients, and via the -p <port> flag in psql. The port is the right answer for almost every connection, and the port is the wrong answer when an admin has moved Postgres to a different port (usually for security-through-obscurity, multi-instance co-location, or to avoid a port conflict with another service).
Why 5432, not 3306, not 5433
The short version of the history is that Postgres was originally developed at Berkeley in the 1980s and 1990s, the project predates the IANA service-name registry, and the project picked 5432 as a high, unused TCP port that was unlikely to conflict with the well-known ports (0 to 1023) and the registered ports (1024 to 49151) that were in use at the time. The number was not assigned by IANA — the number was just chosen by the developers. The IANA later formalized the assignment, and the postgresql service name resolves to 5432 in /etc/services and in the modern getservbyname() resolution.
The number is not 3306 because that port was already in use by MySQL (the well-known port for MySQL, picked for similar reasons by the MySQL team at TcX around the same era). The number is not 5433 because 5433 is the port the Postgres installer falls back to when 5432 is already in use (usually because another Postgres instance is running, or because a developer installed Postgres twice and the second install picked the next free port). The number is not 5432 because of any encoding trick or naming convention — the number is just the port the developers picked, and the port has stuck because the entire ecosystem (every libpq client, every ORM, every Docker image, every cloud-managed Postgres) defaults to 5432.
The interesting part of the history is that 5432 is now a soft standard. A database server that is reachable on 5432 is “Postgres” by default. A client that is configured to talk to port 5432 is “talking to Postgres” by default. The number is the API contract, and the API contract is the reason the port is the first thing every developer learns.
How to verify the port on any Postgres server
A short, opinionated list of the four ways to verify the port. The four are the ones a developer will use in real work, and the four are the ones that work on managed, self-hosted, container, and remote servers.
ss -tlnp | grep 5432 (or netstat -tlnp | grep 5432). The command shows the listening TCP sockets and the process that owns them. The output is the most reliable signal that Postgres is actually listening on 5432 on the local server. The command works on every Linux distribution, on macOS (with netstat), and inside a Docker container (where the command shows the listener inside the container’s network namespace).
SHOW port; in psql. The command shows the port the server is listening on, from inside the connection. The output is the most reliable signal that the server the client is connected to is actually using 5432 (or whatever the server is configured to). The command works on every managed Postgres service, on every Docker container the developer can psql into, and on every server the developer has a connection string for.
SELECT * FROM pg_settings WHERE name = 'port';. The SQL query returns the same value as SHOW port;, and the query is the form a developer uses in a script. The output is the most reliable signal for a script that needs to verify the port programmatically (a health check, a deploy verification, a connection test).
cat /etc/postgresql/<version>/main/postgresql.conf | grep ^port (or the equivalent path). The command shows the configured port in the server’s configuration file. The output is the most reliable signal that the server will listen on 5432 on next restart, and the output is the one a developer uses when they are debugging “why does this server listen on 5433” (the answer is usually in postgresql.conf).
The four ways cover 99% of real use cases. There is also pg_isready -h host -p port (a connection check, not a port check), nmap -p 5432 host (a port scan, the right answer for a security audit), and the connection string in the application config (the right answer for a quick “is this the right port” check).
How to change the port without breaking clients
A short, opinionated list of the steps to change the port without breaking the seven clients that depend on it. The steps are the ones a developer follows when there is a real reason to move off 5432 (a port conflict, a security policy, a multi-instance deployment), and the steps are the ones that prevent the most common mistakes.
Step 1: update postgresql.conf. Set port = 5433 (or whatever the new port is) in the server’s configuration file. The change requires a server restart to take effect. The change is the server-side half of the port change.
Step 2: update pg_hba.conf (only if needed). The pg_hba.conf file controls host-based authentication, and the file uses CIDR notation, not port numbers. The port is not in pg_hba.conf, and the file usually does not need to change. The exception is when the port is moved across a network boundary, in which case the developer needs to update the listen address (listen_addresses) and the corresponding pg_hba.conf rules.
Step 3: update the PGPORT environment variable (or the connection string). The PGPORT environment variable is read by every libpq client, and the variable is the one a developer sets on the application server. The pattern is export PGPORT=5433 in the shell, or PGPORT=5433 in the systemd unit, or the equivalent in the application’s config (a .env file, a config.yaml, a settings.py).
Step 4: update the connection string. The connection string format is postgresql://user:password@host:port/database. The port goes after the host and before the database. The pattern is the right answer for an ORM (Django, SQLAlchemy, Prisma, Rails), the pattern is the right answer for a BI tool (Metabase, Tableau, Superset), and the pattern is the right answer for any client that does not read PGPORT.
Step 5: update the firewall. The firewall on the server, the firewall on the application server, the security group in the cloud (AWS, GCP, Azure, DigitalOcean, Linode, Vultr), the network policy in Kubernetes. The pattern is the right answer for a developer who is moving the port, and the pattern is the one a developer forgets most often.
Step 6: verify with pg_isready. The pg_isready -h host -p port command returns 0 if the server is reachable on the new port, and the command returns nonzero if the server is not reachable. The pattern is the right answer for a deploy script, and the pattern is the right answer for a developer who wants to verify the change before they restart the application.
Step 7: update monitoring and alerting. The connection pool monitor (pgbouncer, pgpool, RDS Performance Insights, Datadog Postgres integration), the uptime checker (Pingdom, UptimeRobot, BetterStack), the deployment verification (a health check endpoint, a smoke test). The pattern is the right answer for a developer who is moving the port in production, and the pattern is the one a developer forgets until the monitor page is red.
The seven steps are the pattern. A developer who follows the seven is a developer who can change the port in 10 minutes. A developer who skips a step is a developer who is going to spend an hour debugging a connection refused error.
The five other ports in the Postgres ecosystem
A short, opinionated list of the five other ports a developer ends up needing. The five are the ones that show up in real Postgres deployments, and the five are the ones the developer should know.
5433. The first-fallback port. The Postgres installer picks 5433 when 5432 is already in use (usually because another Postgres instance is running, or because a developer installed Postgres twice). The port is the right answer for a developer who is running multiple Postgres instances on the same machine, and the port is the one a developer sees in pg_lsclusters on a Debian/Ubuntu system.
5434 (and higher). The second-fallback (and so on). The installer picks 5434 when both 5432 and 5433 are in use, and the pattern continues. The port is rare in practice, and the port is the one a developer sees when they are running several Postgres instances for testing or for multi-tenancy on a single host.
The pg_ctl debug port. Postgres does not have a dedicated debug port, but the postgres server can be run with the -d <debug-level> flag and the port=5432; pgsql_debug_port=... settings in postgresql.conf. The port is for connection-time debugging (TLS, auth, GUC parsing), and the port is the one a developer sees when they are debugging “why is this connection being rejected.”
The WAL receiver port (5432 by default, with replication). Postgres uses the same port (5432) for streaming replication, but the server requires a separate pg_hba.conf entry and a separate user with the REPLICATION privilege. The port is the right answer for a developer who is setting up a replica, and the port is the one a developer configures on the primary_conninfo string on the replica.
The pgbouncer/pgpool port (usually 6432). A connection pooler (pgbouncer, pgpool) usually listens on a different port (6432 is the de facto convention) and forwards connections to the real Postgres port. The port is the right answer for a developer who is pooling connections, and the port is the one a developer configures on the application’s connection string. The pattern is the right answer for a high-traffic application that has more application servers than database connections can support.
The five ports are the floor. There is also the pg_stat_statements collector (no separate port), the postgres_fdw foreign data wrapper (uses the normal 5432), the pglogical extension (uses replication on 5432), and the pgcat connection pooler (uses a custom port). The five are the ones a developer should know first.
The seven gotchas when wiring up 5432 in production
A short, opinionated list of gotchas that have actually broken real Postgres deployments. None of them are dramatic. They are the boring ones.
The port is open on localhost but not on the public interface. A default Postgres install binds to localhost (or to the 127.0.0.1 loopback), which means the port is reachable from the server itself but not from anywhere else. The fix is to set listen_addresses = '*' in postgresql.conf (or to a specific IP), and the fix is the lever that turns “I cannot connect from the app server” into “I can connect from the app server.”
The port is open on the public interface but the firewall blocks it. A server that has Postgres bound to * is a server that the developer’s local firewall (ufw, firewalld, iptables) and the cloud security group (AWS, GCP, Azure) are both blocking. The fix is to open the port in the local firewall (ufw allow 5432) and in the cloud security group, and the fix is the lever that turns “I can connect locally but not from the app server” into “I can connect from anywhere.”
The pg_hba.conf rule uses md5 or scram-sha-256 but the password is wrong. A connection that gets past the firewall and the bind but fails on authentication is a connection that returns “password authentication failed for user.” The fix is to reset the password (ALTER USER <name> PASSWORD '<new>';), and the fix is the lever that turns “I cannot connect” into “I can connect.”
The application uses a connection string with the wrong port. An ORM (Django, SQLAlchemy, Prisma, Rails) that has a connection string like postgresql://user:password@host:3306/database is an ORM that is going to fail with “connection refused” (or, worse, succeed against a MySQL server that happens to be running on 3306). The fix is to use 5432, and the fix is the lever that turns “the database type is wrong” into “the database type is Postgres.”
The port is moved but the PGPORT environment variable is not updated. A developer who moves the port to 5433 in postgresql.conf but forgets to update PGPORT on the application server is a developer whose psql and createdb and pg_dump are all going to fail (because they default to 5432). The fix is to set PGPORT=5433 in the application’s environment, and the fix is the lever that turns “the CLI tools cannot connect” into “the CLI tools can connect.”
The Docker port mapping is 5432:5432 but the container’s Postgres is on 5433. A developer who runs docker run -p 5432:5432 postgres and the container’s Postgres is configured to listen on 5433 is a developer whose port mapping points at nothing. The fix is to make the port mapping match the container’s actual port (5433:5433 or 5432:5433), and the fix is the lever that turns “the port mapping is broken” into “the port mapping is correct.”
The managed Postgres service is on a non-standard port. A managed Postgres service (RDS, Cloud SQL, Azure Database, Supabase, Neon, Crunchy Bridge) that puts Postgres on a non-standard port (5433, 6543, or a custom port for the connection pooler) is a service that requires the developer to use the port from the service’s connection string, not 5432. The fix is to read the connection string from the dashboard, and the fix is the lever that turns “I am using 5432 by default” into “I am using the right port.”
The way Docker and managed services handle 5432
A short, opinionated list of the patterns Docker and managed services use for 5432. The patterns are the ones a developer will see most often, and the patterns are the ones the developer should know.
The postgres:16 Docker image. The official postgres image on Docker Hub listens on 5432 inside the container, and the image has no port mapping by default. The pattern is the right answer for a developer who wants to run Postgres locally, and the pattern is docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=... postgres:16.
The postgres:16 Docker image with a custom port. A developer who wants to map the container’s 5432 to the host’s 5433 (e.g. to avoid a conflict with a local Postgres install) is a developer who uses docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=... postgres:16. The pattern maps the host’s 5433 to the container’s 5432, and the pattern is the right answer for a developer who is running multiple Postgres instances.
Docker Compose with Postgres. A two-service Compose file (one for Postgres, one for the application) uses ports: - "5432:5432" for the Postgres service and reads the host from the application service (which is on the same Compose network). The pattern is the right answer for local development, the pattern is the right answer for a CI test, and the pattern is the right answer for a sandbox environment.
AWS RDS for PostgreSQL. RDS creates a Postgres instance with a connection string like mydb.123456789012.us-east-1.rds.amazonaws.com:5432. The port is 5432 by default, and the port is overridable when the developer creates the instance. The pattern is the right answer for a managed Postgres service, and the pattern is the one a developer configures in the RDS dashboard.
Google Cloud SQL for PostgreSQL. Cloud SQL creates a Postgres instance with a connection string that uses the instance’s public IP and port 5432. The port is 5432 by default, and the port is overridable when the developer creates the instance. The pattern is the right answer for a managed Postgres service, and the pattern is the one a developer configures in the Cloud SQL dashboard.
A connection pooler (pgbouncer, pgpool, Supabase’s “Transaction” pooler). A pooler usually listens on a different port (Supabase’s “Transaction” pooler is on 6543, pgbouncer defaults to 6432). The pattern is the right answer for a developer who is pooling connections, and the pattern is the one a developer configures in the application’s connection string.
The six patterns are the floor. There is also Azure Database for PostgreSQL, DigitalOcean Managed Postgres, Crunchy Bridge, Neon, Supabase, Render Postgres, and others. The six are the ones a developer should know first, and the six are the ones a developer will see most often.
How this fits the rest of the stack
A database port rarely lives in isolation. The port is usually part of a stack (an application, a database, a static site, a worker) that runs on a platform. The platform that handles the port should make the rest of the stack feel like part of the same conversation.
The services layer is the part of the platform that runs the long-lived API the database serves. The database layer is the part that holds the data the API reads and writes. The static layer is the part that hosts the dashboard the developer uses to manage the database. The environment variables are the part that holds the connection string the API uses to connect.
A database on a platform where the service, the database, the storage, and the secrets are all in the same place is a database the team is going to be able to operate. A database on a platform where each piece is in a different console is a database the team is going to spend the first hour just opening the right tab.
For a team that wants to see the full cost of the project before it commits, the RunxBuild hosting calculator shows the line items together. The API, the database, the storage, the worker, the bandwidth — each one is a separate number, and the team’s mental model for the platform is the sum of those numbers.
FAQ
What is the default port for PostgreSQL?
The default port for PostgreSQL is 5432. The port is compiled into the postgres server binary and into every libpq-based client (psql, pg_dump, pg_isready, etc.). The port is also the one the IANA has assigned to the postgresql service name. The port is overridable via postgresql.conf, the PGPORT environment variable, and the -p flag in psql.
How do I check what port Postgres is using on a server?
Use SHOW port; in psql, or SELECT * FROM pg_settings WHERE name = 'port'; as a SQL query, or cat /etc/postgresql/<version>/main/postgresql.conf | grep ^port in the shell. The first two work on every Postgres server, the third works on Debian/Ubuntu systems. The output is the most reliable signal of the port the server is actually using.
How do I change the port Postgres listens on?
Edit postgresql.conf and set port = <new-port>, then restart the server. Then update PGPORT on the application server, update the application’s connection string, update the firewall rules, and verify with pg_isready -h host -p <new-port>. The change is the right answer for a port conflict, a security policy, or a multi-instance deployment.
Why is Postgres on port 5432 specifically?
The port was picked by the original Berkeley developers in the 1990s as a high, unused TCP port that was unlikely to conflict with the well-known and registered ports of the era. The IANA later formalized the assignment for the postgresql service name. The number is not a code or an encoding — it is just the number the developers chose, and the number has stuck because the entire ecosystem defaults to it.
What port does PostgreSQL use for replication?
The same port — 5432. Postgres uses the same TCP port for replication as for normal connections, and the server requires a separate pg_hba.conf entry and a separate user with the REPLICATION privilege. The port is the right answer for streaming replication, and the port is the one a developer configures on the primary_conninfo string on the replica.
What port does a Postgres connection pooler use?
It depends. pgbouncer defaults to 6432 (a port chosen to be “one above” 5432). pgpool defaults to 9999. Supabase’s “Transaction” pooler is on 6543. The port is the right answer for the application to connect to, and the pooler forwards the connection to Postgres on 5432. The pattern is the right answer for a high-traffic application that has more application servers than database connections can support.
Is port 5432 open by default on a fresh Postgres install?
No. A fresh Postgres install binds to localhost (or 127.0.0.1), which means the port is reachable from the server itself but not from anywhere else. To make Postgres reachable from a remote application server, the developer needs to set listen_addresses = '*' (or to a specific IP) in postgresql.conf, open the port in the local firewall, and open the port in the cloud security group.