PostgreSQL’s default port is 5432. Full stop. Every managed Postgres you can sign up for in 2026 — RunxBuild, Neon, Supabase, AWS RDS, Crunchy, DigitalOcean, the self-hosted box under your desk — accepts a connection on 5432 by default. The reason for that number is a 1996 committee meeting, the reason it survived is a 28-year-long compatibility promise, and the reason you should care is the three real situations where changing it does something useful for you.
This post answers the actual question, then explains the part the docs don’t bother with: when 5432 is the right choice (almost always), when it isn’t (rare but real), and what every connection string in your codebase is actually doing when you omit the port.
Table of contents
- The one-paragraph answer
- Where 5432 came from
- What every Postgres client does with the port
- The connection string, fully decoded
- Why every cloud Postgres still uses 5432
- The three situations where you should change the port
- What “production-ready Postgres” actually requires in 2026
- A small collection of port-related mistakes worth not making
- The answer you actually need
- FAQ
The one-paragraph answer
Postgres listens on TCP port 5432 by default. A connection string can either include the port explicitly — postgresql://user:[email protected]:5432/mydb — or omit it, in which case every Postgres client, driver, and CLI falls back to 5432. The fallback is enforced by the libpq source code itself, so omitting the port works the same way in psql, pg_dump, psycopg, node-postgres, SQLAlchemy, drizzle, prisma, every ORM, and every language binding. You don’t need to remember this; the library does.
That is the answer. The rest of this post is the part the docs cover in three sentences and the Stack Overflow answers cover in a flamewar: where 5432 came from, why it stuck, and the three production cases where a different port is the right call.
Where 5432 came from
Postgres started in 1986 as a research project at UC Berkeley under the name POSTGRES, then renamed to PostgreSQL and went open-source in 1996. The default port was assigned during the 1995–1996 IANA port registration period, before Postgres 6.0 shipped.
The IANA Service Name and Transport Port Number Registry doesn’t tell a story about why 5432 in particular. What it tells you is that no higher-priority service claimed it, that the application maintainers registered it before anybody else could, and that the number has been stable ever since. There is no “5432 means something” folklore. It is a registration slot that the project took and never gave up.
The Postgres project formally registered port 5432 with IANA. The assignment has been stable through every major release from 6.0 to 18, through every enterprise fork, and through the entire era of cloud-managed databases that are now the default way teams use Postgres at all.
This matters because: the port number is a promise. Every client, every driver, every ORM, every CLI, every cloud provider, every Docker image, every tutorial, every Stack Overflow answer, and every piece of training data assumes 5432. Changing the default would break one of the largest, oldest compatibility contracts in the database world. The project has zero reason to do that and a thousand reasons not to.
What every Postgres client does with the port
This is the part that earns the word “default” in “default port.” When you write a connection string without a port, this is what happens, in order, on every Postgres client:
- Check the connection string for an explicit
port=...parameter or a:NNNNsegment in the URI. - If absent, check the
PGPORTenvironment variable. - If unset, check the connection service file (
~/.pg_service.conf) for aport=entry. - If unset, fall back to the compiled-in default, which is
5432.
This fallback lives in libpq, the official Postgres C client library. Every other client — psycopg, node-postgres, the Go pgx driver, the Java JDBC driver, the .NET Npgsql driver, every ORM that speaks the Postgres wire protocol — either calls libpq underneath or reimplements this exact same four-step lookup. The result is identical: omit the port, get 5432.
You can verify this from your terminal in five seconds. With any Postgres client:
# Connection string WITH the port
psql "postgresql://user:[email protected]:5432/mydb"
# Connection string WITHOUT the port
psql "postgresql://user:[email protected]/mydb"
# Both work identically. The second one is using the 5432 default.
The second form is not relying on the server being “nice” about unknown ports. It is calling libpq, which checks the compiled default, which is 5432, which is what the server is listening on. Both ends of the connection agree, and the connection happens.
The connection string, fully decoded
Here is what every part of a Postgres connection string does, with explicit attention to the port slot:
postgresql://[user[:password]@][host][:port][/dbname][?param1=value1&...]
When the port is omitted, libpq walks this list in order:
portparameter in the URI query string —?port=5432wins everything.:NNNNsegment in the URI authority —:5432between host and dbname.PGPORTenvironment variable —export PGPORT=5432before running psql.- Service file entry —
~/.pg_service.confwithport=5432. - Compiled-in default — 5432.
All five paths converge on 5432, which is what you want. The reason this is the right design is the same reason DNS works: a sensible default is a contract between every client and every server that lets you omit the boring part and still get the correct answer. The boring part here is the port. Omitting it should be free, and it is.
The official Postgres documentation on connection strings is at postgresql.org/docs/current/libpq-connect.html and it covers all of this in detail if you want to read the libpq source yourself. The practical takeaway is: don’t put the port in your connection string unless you are changing it. The default will work, your secrets manager will have one less field to manage, and your code will be portable to any Postgres deployment that follows the convention.
Why every cloud Postgres still uses 5432
Every managed Postgres you can sign up for today uses 5432. RunxBuild, Neon, Supabase, AWS RDS, Google Cloud SQL, DigitalOcean, Crunchy Bridge, Aiven, Render, Heroku Postgres. Some of them let you run the database behind a connection pooler on a different port (the pooler usually lives on 5432 too, with the database on the internal network on a different port), but the public-facing port that every client connects to is 5432.
The reason is the same compatibility promise as before, but at larger scale. A developer who learns the convention “Postgres lives on 5432” once in 2010 can connect to a managed database in 2026 without reading the docs. The convention is the value. Breaking it would burn the value for no gain.
There is a corollary, which is that “I’m going to use a non-default port for security” is almost always the wrong reason to change the port. Security through port obscurity is a defense-in-depth measure that is fine to add to a real security posture, but it is not a substitute for a real security posture. The 5% of attackers who run port scans find your database regardless. The 95% who don’t run port scans were never going to find you anyway. Spend the security budget on TLS, authentication, and network segmentation instead.
The three situations where you should change the port
This is the part nobody writes about because it doesn’t fit the “Postgres is great, here is a connection string” blog post. The port is the right thing to think about in three production scenarios, and in all three the answer is the same: keep the same default on the outside, run a different port on the inside.
Situation 1: Running multiple Postgres instances on the same host
The most common reason to change the port. If you have a single VM and you want to run two Postgres instances on it — say, a development database and a staging database — the second one has to listen on a different port or the OS will refuse to bind both to 5432. The convention is to put the second instance on 5433, the third on 5434, and so on.
You configure this in postgresql.conf:
port = 5433
You also need to make sure the second instance has a separate data directory, a separate pg_hba.conf, a separate log file, and a separate systemd unit (or however you run services on the host). None of that is automatic. The port is the visible part; the configuration underneath it is the actual work.
In practice, nobody does this anymore for new projects. The default in 2026 is one managed Postgres per environment, and the environment isolation comes from the cloud account, the VPC, or the project namespace — not from the port. But if you are maintaining a legacy setup with multiple instances per host, the port convention is 5432, 5433, 5434.
Situation 2: The database sits behind a connection pooler
PgBouncer, Pgpool-II, and the connection poolers built into managed Postgres platforms (including RunxBuild) all sit between the application and the database. The application talks to the pooler on one port; the pooler talks to Postgres on another. The pooler port is almost always 6432 (note the leading 6) — Postgres’ way of saying “I’m a pooler, not the real database, but you can pretend I’m Postgres.”
You configure the application to point at the pooler port, and the pooler handles connection pooling, transaction pooling, and (depending on mode) statement pooling. The database itself stays on 5432 on the internal network. The application never talks to the real database port. The pooler becomes the load-bearing surface, and you can do things like restart the database, fail over to a replica, or run a maintenance migration without the application noticing.
If you are deploying a FastAPI app to a managed platform that exposes both the database port (5432) and a pooler port (usually 6432), the right answer is to point your app at the pooler port. The database port is for migrations and admin. The pooler port is for the request path.
Situation 3: The database is behind a non-standard network path
If you put a Postgres instance behind a non-standard proxy, a sidecar, a wire-protocol translator, or an SSH tunnel, that proxy will listen on whatever port you tell it to. The conventions:
5432for the real Postgres port (or the pooler, if you use one).6432for PgBouncer or a generic pooler.25432or35432are sometimes used for PgBouncer in transaction-pooling mode, but this is platform-specific.- Any port you like for a custom sidecar, as long as you document it.
The principle is the same: pick a port, document it, stick to it. The Postgres default is the default because the whole ecosystem assumes it. If you have a real reason to deviate, deviate — but document the reason in your infrastructure README so the next person doesn’t have to reverse-engineer it.
What “production-ready Postgres” actually requires in 2026
This is the part of the post that the docs don’t write because the docs are written by people who already know it. The number 5432 is the smallest fact. The rest of the production story is the part you actually have to get right.
Managed Postgres with backups and point-in-time recovery. You should not be SSHing into a box to recover a WAL archive. You should be clicking a button in a dashboard to restore from yesterday’s snapshot. Every platform that has “Postgres” in the marketing has this; pick one and stop worrying about it.
Connection pooling in front of the database. Every serverless function, every short-lived container, every microservice that opens a new connection per request will exhaust your database connection limit on a Friday afternoon. A pooler (PgBouncer, or the platform’s built-in pooler) keeps the connection count sane. If your platform exposes both 5432 and 6432, use 6432 from the application.
TLS for the connection. sslmode=require is the minimum. sslmode=verify-full is the right answer. The connection string is postgresql://user:[email protected]:5432/mydb?sslmode=verify-full. Don’t negotiate this with yourself. Just set it.
Strong authentication. The default md5 authentication is deprecated and will be removed. Use scram-sha-256. If your platform supports certificate auth or OAuth, use that for the application user. The postgres superuser is for migrations and admin only; the application gets its own user with the minimum privileges it needs.
A health check that actually exercises the database. A /health endpoint that pings Postgres with a one-row SELECT 1 is the difference between “the app is up” and “the app is up and the database is up.” The 2am page that you don’t get paged for is the one where the app container is running but the connection to the database is broken and the app is silently returning 500s to real users. The health check is what makes your platform’s auto-restart logic actually do something.
None of this is about the port. All of it is about the same underlying idea: the port is the address. The real work is everything you do once you arrive.
A small collection of port-related mistakes worth not making
A short list, in the spirit of “things I have seen go wrong and would like to not see go wrong again”:
Mistake 1: hardcoding the port in a config file that ships to multiple environments. The right pattern is to omit the port from the connection string and let libpq default to 5432, or to read the port from an environment variable that’s set per environment. The wrong pattern is connection_string = "postgresql://user:[email protected]:5432/mydb" in a config file that gets reused for production, staging, and local development. The day you run a second database on a non-default port, this code breaks in production in a way that doesn’t show up in local.
Mistake 2: setting port = 5432 in postgresql.conf for security. It’s already the default. Setting it explicitly doesn’t add any security and it confuses the next person who reads the config.
Mistake 3: changing the port for “obscure port” reasons, then documenting it in one place. If the port change is real, it should be in the env var, the README, the runbook, the onboarding doc, and the deploy config. If you can find the change in only one of those five places, you have not documented it; you have just hidden it.
Mistake 4: assuming a custom port on a managed platform is honored. Many managed Postgres providers ignore the port parameter in the connection string entirely; they only let you connect on the port they expose. If you are on a managed platform, check the platform’s docs for the supported ports. The default is always supported. Other ports are sometimes not.
Mistake 5: confusing the database port with the pooler port. The application talks to the pooler. The pooler talks to the database. Pointing the application at the database port is a perfectly good way to exhaust the database’s connection limit. If your platform exposes both, read the docs about which one is the right one to use for production traffic, and use the other for migrations.
The answer you actually need
PostgreSQL’s default port is 5432. It has been 5432 since the project registered the port with IANA in 1996, and it will be 5432 in 2030. Every client you will ever use falls back to 5432 when the port is omitted. Every cloud Postgres you can sign up for in 2026 accepts connections on 5432.
Write your connection strings without the port. Document the database URL once, in the README, with the password replaced by ${DATABASE_PASSWORD} and a note that the real value lives in the deployment platform’s secret store. Run a connection pooler in front of the database and point your application at the pooler port. Set sslmode=verify-full and never negotiate this with yourself. Set a budget alert before you need it.
That is the whole story. The number is 5432. The number will always be 5432. Don’t overthink the number; the work that matters is everything around it.
Frequently asked questions
What is the default port for PostgreSQL?
PostgreSQL’s default port is 5432. Every Postgres client, every Postgres CLI, every Postgres driver, and every cloud Postgres platform falls back to 5432 when the port is omitted from the connection string. The default has been stable since 1996 and is registered with IANA.
Is it safe to leave the port out of a Postgres connection string?
Yes. The libpq client library, which is the reference implementation that every other driver and ORM inherits behavior from, defaults to 5432 when no port is specified. Omitting the port produces the same connection as specifying port=5432. The advantage of omitting it is portability: the same connection string works on every Postgres deployment that follows the convention.
Can I change the default Postgres port?
Yes. Set port = NNNN in postgresql.conf and restart the database. The most common reason to change the port is running multiple Postgres instances on the same host. Production servers and managed databases have no reason to change the port and many reasons not to.
What port does PgBouncer use?
PgBouncer typically listens on 6432 when used as a connection pooler in front of Postgres. The leading 6 is a convention, not a standard. Some platforms use other ports (RunxBuild uses its own pooler endpoint; AWS RDS Proxy has its own port; Heroku Postgres exposes a pooler URL on a non-default port). Check the platform’s documentation for the exact port.
Is changing the Postgres port a security best practice?
No. Security through port obscurity is a weak defense-in-depth measure, not a primary security control. The 5% of attackers who run port scans will find your database regardless of the port. Spend the security budget on TLS (sslmode=verify-full), strong authentication (SCRAM-SHA-256 or certificate auth), and network segmentation. Keep the default port unless you have a real reason to change it.
Why does the Postgres port default to 5432?
The number 5432 was assigned to Postgres during the 1995–1996 IANA port registration period, before Postgres 6.0 shipped in January 1997. The exact reason for 5432 specifically is “no higher-priority service claimed it and the project maintainers registered it.” The number has been stable ever since, and the project has zero incentive to change a port that an entire ecosystem has spent 30 years depending on.
How this fits the rest of the stack
The default port is also a hosting cost signal — every open port is a surface the team has to defend, every private network is a feature the team has to pay for, and every firewall rule is a configuration the team has to maintain. The team’s mental model for the database cost is the instance, the storage, the bandwidth, and the private network. The RunxBuild hosting calculator is the right place to model that — pick the database tier, the storage, the bandwidth, and the private network feature, and the calculator shows what the production database costs at the team’s actual usage.
Useful related references: