Limited Time Offer: 40% off

PostgreSQL connect to database (and the USE equivalent)

Switch databases with \c, connect with psql -d or a connection URI. There is no USE command in Postgres.

Quick answer

Already in psql, switching to another database:

\c mydb

Starting a new psql session against a database:

BASH
psql -d mydb

With a full connection string:

BASH
psql "postgresql://myuser:secret@localhost:5432/mydb"

If you came here because USE mydb; gave you a syntax error, the next section is for you.

Why USE does not work in PostgreSQL

USE is a MySQL and SQL Server command. PostgreSQL has no equivalent statement, and it does not tell you that:

SQL
USE mydb;
ERROR:  syntax error at or near "USE"
LINE 1: USE mydb;
        ^

That is the whole error. There is no hint, no suggestion, and no mention of \c. PostgreSQL's parser has never heard of USE, so it fails at the first word and stops.

The equivalent is the psql meta-command \c:

\c mydb
You are now connected to database "mydb" as user "postgres".

\connect is a longer alias for the same command.

SET search_path is not the same as USE

This comes up constantly, and it is wrong often enough to be worth stating plainly.

SQL
SET search_path TO mydb;

That does not switch databases. search_path selects a schema, not a database, and the two are different things in PostgreSQL:

  • A database is an isolated container. You connect to exactly one at a time, and a single connection cannot query across databases.
  • A schema is a namespace inside a database. public is the default one. You can query across schemas freely within one connection.

MySQL blurs this: what MySQL calls a "database" behaves much more like a PostgreSQL schema, which is why USE feels like it should map onto SET search_path. It does not. If you are coming from MySQL and want the thing that behaves like USE, and you are working inside one database, SET search_path TO myschema; may genuinely be what you want. If you want a different database, you need \c and a new connection.

Coming from MySQL

MySQLPostgreSQL
USE mydb;\c mydb
SHOW DATABASES;\l
SHOW TABLES;\dt
DESCRIBE mytable;\d mytable
SELECT DATABASE();SELECT current_database();

See PostgreSQL list databases for the SHOW DATABASES equivalent.

Switching databases with \c

The \c command takes several forms:

\c mydb                          -- switch database, keep current user
\c mydb alice                    -- switch database and user
\c - alice                       -- keep database, switch user
\c mydb alice db.example.com 5432 -- database, user, host, port
\c                               -- reconnect with the same parameters

The - is a placeholder meaning "keep the current value".

\c opens a new connection

This is the part that matters and almost nobody mentions. \c does not switch context inside your session. It closes your connection and opens a new one, which means you get a completely new backend process.

Watch the backend PID change:

SQL
SELECT pg_backend_pid();
 139
\c mydb
SELECT pg_backend_pid();
 140

Different process. Anything tied to the old session is gone:

SQL
CREATE TEMP TABLE probe(x int);
\c mydb
SELECT count(*) FROM probe;
ERROR:  relation "probe" does not exist

Temporary tables, prepared statements, and session settings set with SET all disappear. This happens even if you reconnect to the same database, because the reconnection is what destroys them, not the change of database.

If you need session state to survive, do not use \c.

The -reuse-previous trap

\c reuses your previous connection parameters, but only in the positional form. Pass a connection string and it does not:

\c "host=localhost port=5432 dbname=mydb"
\connect: connection to server ... FATAL:  role "root" does not exist

It silently dropped the username and fell back to your operating system user. The documented behaviour is that parameters are re-used with the positional syntax but not when a conninfo string is given. Force it:

\c -reuse-previous=on "dbname=mydb"

One more thing worth knowing: if \c fails in an interactive session, psql keeps your old connection. In a non-interactive script it does not, and the old connection is closed. A failed \c in a script leaves you with nothing.

Connecting from the shell with psql

The four flags you need:

BASH
psql -h localhost -p 5432 -U myuser -d mydb
FlagMeaningDefault
-hhostlocal Unix socket
-pport5432
-Uuseryour OS username
-ddatabasesame as the username

Note that -d defaults to your username, not to postgres. That is why psql on its own often fails with database "yourname" does not exist.

Shorthand: the first bare argument is treated as the database name, so these are equivalent:

BASH
psql -d mydb
psql mydb

Connection strings and URIs

Every hosted Postgres provider hands you a connection URI, so it is worth knowing the format:

postgresql://[user[:password]@][host][:port][/dbname][?param=value]
BASH
psql "postgresql://myuser:secret@db.example.com:5432/mydb?sslmode=require"

postgres:// works as a scheme too. Quote the whole thing, because ? and & mean something to your shell.

Useful variations:

BASH
# Unix socket via URI
psql "postgresql:///mydb?host=/var/run/postgresql"

# Multiple hosts, tried in order until one connects
psql "postgresql://host1:5432,host2:5432/mydb"

# IPv6, in brackets
psql "postgresql://[::1]:5432/mydb"

Any special characters in a password must be percent-encoded. A password containing @ will otherwise be read as the start of the hostname.

URI parameters override flags

If you pass both, the connection string wins:

BASH
psql -p 1234 -d "postgresql://postgres@127.0.0.1:5432/mydb"

That connects on 5432, not 1234. The -p flag is silently ignored. This is documented behaviour, not a bug, and it is a good reason not to mix the two styles.

Passwords: PGPASSWORD, .pgpass, and prompts

By default psql prompts for a password. For scripts, you have three options.

PGPASSWORD works but the PostgreSQL docs specifically advise against it, because on many systems any user can read another process's environment via ps:

BASH
PGPASSWORD=secret psql -h localhost -U myuser -d mydb

A password file is the recommended approach. Create ~/.pgpass:

hostname:port:database:username:password
db.example.com:5432:mydb:myuser:secret

Any field can be * to match anything. The file must not be readable by anyone else:

BASH
chmod 0600 ~/.pgpass

Get that wrong and psql ignores the file and tells you why:

WARNING: password file "/home/you/.pgpass" has group or world access; permissions should be u=rw (0600) or less

A connection service file (~/.pg_service.conf) is worth knowing about if you juggle several servers, letting you connect with psql service=prod.

Environment variables

psql reads these when the equivalent flag is absent:

VariableEquivalent
PGHOST-h
PGPORT-p
PGUSER-U
PGDATABASE-d
PGPASSWORD(see above)
PGPASSFILEpath to the password file
PGSSLMODEsslmode=

Precedence, highest first: connection string parameters, then command-line flags, then environment variables, then built-in defaults.

Checking your connection with \conninfo

When you are not sure where you actually are:

\conninfo

On PostgreSQL 18 and later this prints a table:

      Connection Information
      Parameter       |   Value
----------------------+-----------
 Database             | mydb
 Client User          | postgres
 Host                 | 127.0.0.1
 Server Port          | 5432
 Protocol Version     | 3.0
 Password Used        | false
 Backend PID          | 125
 SSL Connection       | false
 Superuser            | on
 Hot Standby          | off
(12 rows)

Over a Unix socket, Host is replaced with Socket Directory.

On PostgreSQL 17 and earlier it is a single line:

You are connected to database "mydb" as user "postgres" via socket in "/tmp" at port "5432".

The tabular format is new in PostgreSQL 18. Backend PID being listed there is handy for confirming the \c-makes-a-new-connection behaviour described above.

Connecting to Postgres in Docker

If Postgres runs in a container, the simplest path is to run psql inside it:

BASH
docker exec -it postgres psql -U postgres -d mydb

This uses the container's Unix socket, which is trusted, so it never asks for a password. That also means it is not a test of whether your password works.

From your host, connect normally, provided the port is published with -p 5432:5432:

BASH
psql -h localhost -p 5432 -U postgres -d mydb

From another container, use the service name as the host, not localhost:

BASH
psql -h postgres -p 5432 -U postgres -d mydb

Inside a container, localhost refers to that container. See Postgres Docker: The Complete 2026 Guide for the full setup.

Connecting to a remote server

Three things have to be true, and the error you get tells you which one is not.

  1. The server listens on an external address (listen_addresses in postgresql.conf, commonly '*').
  2. pg_hba.conf has a rule permitting your client address, user, and database.
  3. The port is reachable through any firewall.

Require encryption in transit:

BASH
psql "postgresql://myuser@db.example.com:5432/mydb?sslmode=require"

sslmode=require encrypts but does not verify who you are talking to. For that, use verify-full with a CA certificate. On an untrusted network, require alone does not protect you from an active attacker.

Common connection errors

database "mydb" does not exist

psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL:  database "mydb" does not exist

The database is not there, or you are on the wrong server. List what exists with psql -l. If you ran bare psql and saw your own username in the message, that is -d defaulting to your username. See database does not exist.

role "myuser" does not exist

psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL:  role "myuser" does not exist

-U defaults to your OS username, so this usually means you did not pass -U at all. See PostgreSQL CREATE USER.

password authentication failed

psql: error: connection to server at "127.0.0.1", port 5432 failed: FATAL:  password authentication failed for user "postgres"

Wrong password, or the wrong pg_hba.conf rule matched. Remember that connecting over a local socket often uses trust and never prompts, so a working socket connection proves nothing about your password. See invalid password.

Connection refused

psql: error: connection to server at "127.0.0.1", port 59999 failed: Connection refused
	Is the server running on that host and accepting TCP/IP connections?

Nothing is listening there. Wrong port, server not running, or it is not listening on that address. See connection refused.

No such file or directory

psql: error: connection to server on socket "/var/run/nope/.s.PGSQL.5432" failed: No such file or directory
	Is the server running locally and accepting connections on that socket?

The socket-connection version of the same problem. The server is not running locally, or its socket is somewhere other than where psql is looking.

could not translate host name

psql: error: could not translate host name "nosuchhost.invalid" to address: Name or service not known

DNS failed. Typo in the hostname, or inside Docker, a container name that is not on your network.

no password supplied

psql: error: connection to server at "127.0.0.1", port 5432 failed: fe_sendauth: no password supplied

The server wants a password and psql had none to give and could not prompt. Common in scripts and cron. Use .pgpass.

psql: command not found

psql is not installed or not on your PATH. On macOS, brew install libpq and add its bin to your path. On Windows, add PostgreSQL's bin directory to PATH.

Quick reference

TaskCommand
MySQL's USE mydb\c mydb
Switch database\c mydb
Switch database and user\c mydb alice
Switch user only\c - alice
Reconnect\c
Connect from the shellpsql -h host -p 5432 -U user -d mydb
Connect with a URIpsql "postgresql://user:pass@host:5432/mydb"
Connect in Dockerdocker exec -it postgres psql -U postgres -d mydb
Where am I connected?\conninfo
Current databaseSELECT current_database();
Password without a prompt~/.pgpass, chmod 0600
Require TLS?sslmode=require
Quit\q