Secure connections
Save PostgreSQL connection details with encrypted passwords, SSL settings, URL import, testing, search, edit, and delete actions.
Connect to remote PostgreSQL
Remote connection failures fall into four buckets, and the error message tells you which one you are in. Reading it before changing anything saves most of the time people spend on this.
Short answer: A timeout means packets are being dropped: a firewall or security group. Connection refused means you reached the host but nothing is listening on that port, usually listen_addresses. A pg_hba error means the network is fine and only the access rule needs changing. For production, prefer an SSH tunnel over opening port 5432 at all.

PgDeck is shaped around PostgreSQL tasks that happen every day: connect, inspect, filter, edit, query, manage structure, copy, and export.
Save PostgreSQL connection details with encrypted passwords, SSL settings, URL import, testing, search, edit, and delete actions.
Browse schemas and tables, search the table list, pin favorites, filter rows, sort columns, resize columns, and paginate results.
Run SELECT and non-SELECT statements from multi-tab SQL editors with syntax highlighting and interactive query results.
Edit cells, add rows, duplicate rows, set NULL, stage deletes, review pending changes, and commit everything in one transaction.
These three errors point at three different layers, and fixing the wrong one wastes an afternoon. A hang then timeout is a dropped packet — firewall. An immediate refusal is nothing listening — listen_addresses or the wrong port. A message naming pg_hba.conf means you connected successfully and only the access rule is missing.
# Is anything listening at all?
nc -zv db.example.com 5432
# Or with psql, which reports the real error
psql "postgres://user@db.example.com:5432/mydb"By default PostgreSQL binds only to localhost, so remote connections are refused immediately no matter what the firewall allows. listen_addresses changes that. This one requires a full restart — a reload is not enough.
# postgresql.conf
listen_addresses = '*' # or a specific interface IP
sudo systemctl restart postgresqlpg_hba.conf decides who may connect from where and how they authenticate. Rules are read top to bottom and the first match wins. Use scram-sha-256, never trust — trust accepts any connection with no password at all. Restrict the source range as tightly as you can; a /32 for a single host is ideal.
# pg_hba.conf — hostssl also requires encryption
# TYPE DATABASE USER ADDRESS METHOD
hostssl mydb app 203.0.113.7/32 scram-sha-256
SELECT pg_reload_conf(); -- pg_hba.conf needs only a reloadOn a cloud provider this is the security group; on a plain server it is ufw or firewalld. Allow only the addresses that need access. Exposing 5432 to 0.0.0.0/0 is found by automated scanners within hours and is a standing cause of database compromise.
# Ubuntu, single source address
sudo ufw allow from 203.0.113.7 to any port 5432 proto tcp
# AWS: security group inbound rule, source = your IP, not 0.0.0.0/0An SSH tunnel forwards a local port to the database through a host you already trust, so PostgreSQL stays bound to localhost and the firewall stays closed. Your client then connects to 127.0.0.1 and the traffic emerges on the far side. This is the right default for production.
# Forward local 5433 to the database, via the bastion
ssh -L 5433:localhost:5432 user@bastion.example.com
# Then point the client at:
postgres://user:password@127.0.0.1:5433/mydbKeeping an ssh -L command alive in a terminal works but is easy to lose. Clients with built-in SSH tunnel support open and maintain it as part of the saved connection. PgDeck includes SSH tunnels in the Pro plan, which is the usual way to reach a private RDS instance behind a bastion.
Network reachability, then a listening socket, then the host-based access rule, then the password. Each produces a distinct error, and they must be fixed in that order — there is no point adding a pg_hba rule while a security group is still dropping your packets. Work from the outside in and each step tells you whether to continue.
listen_addresses controls which network interfaces the server binds to at startup, so changing it requires a restart to take effect. pg_hba.conf is re-read on demand, so it only needs a reload. Editing listen_addresses and reloading is a common dead end: the file is correct and the server is still bound to localhost.
Rules are evaluated top to bottom and the first line matching the connection's database, user, and address is applied — even if it rejects and a later line would have accepted. A new rule added at the bottom of a file that already has a broad reject above it will never fire. Order matters more than content here.
The trust method accepts any connection matching the rule with no password whatsoever. It exists for local sockets during initial setup. On a rule covering a network address it means anyone who can reach the port owns the database. If you find trust on a host line in an existing configuration, treat it as an incident rather than a configuration preference.
An exposed 5432 is discovered by internet-wide scanners within hours and subjected to continuous credential attempts. An SSH tunnel means the database is not reachable from the internet at all: authentication happens at the SSH layer with keys rather than passwords, the traffic is encrypted regardless of sslmode, and there is no database port to find. The extra setup is a few lines once, or a field in a client's connection dialog.
More on choosing, comparing, and running a PostgreSQL desktop client.
Set listen_addresses in postgresql.conf and restart, add a matching host or hostssl rule in pg_hba.conf and reload, then allow the port through the firewall from your specific address. For production, prefer an SSH tunnel so the port never needs to be exposed.
A timeout means packets are being dropped, which is a firewall or cloud security group rather than PostgreSQL. Check that inbound TCP 5432 is allowed from your current address. If the connection is refused immediately instead, the problem is listen_addresses or the port, not the firewall.
Good news, mostly: the network is working and you reached the server. PostgreSQL has no rule permitting your address, database, and user combination. Add a host or hostssl line with scram-sha-256 and reload. Remember rules are first-match-wins, so placement in the file matters.
No, a reload is enough — SELECT pg_reload_conf() or systemctl reload postgresql. Changing listen_addresses in postgresql.conf does require a full restart, which is a common reason the change appears to have no effect.
Not to the open internet. Exposed database ports are found by automated scanners within hours and attract continuous credential attempts. Restrict the source to specific addresses at minimum, and preferably keep the port closed and reach the database through an SSH tunnel or a bastion host.