psql Command Line
psql is the official command-line client for PostgreSQL. It is a powerful interactive terminal that lets you run queries, inspect the database schema, import/export data, and manage the server — all without leaving the terminal. Mastering psql dramatically speeds up your PostgreSQL workflow.
Connecting to PostgreSQL
The basic connection syntax:
psql -U username -d database -h host -p port
| Flag | Meaning | Default |
|---|---|---|
-U |
Username | Current OS user |
-d |
Database name | Same as username |
-h |
Host | Local socket (Unix) |
-p |
Port | 5432 |
-W |
Force password prompt | — |
# Connect to local postgres superuser
psql -U postgres
# Connect to a specific database
psql -U postgres -d myapp
# Connect to a remote server
psql -U myuser -d production -h db.example.com -p 5432
# Connection string format (URL)
psql "postgresql://myuser:mypassword@db.example.com:5432/production"
# Using environment variables (recommended for scripts)
export PGHOST=db.example.com
export PGUSER=myuser
export PGDATABASE=production
psql # uses env vars automatically
~/.pgpass file (format: hostname:port:database:username:password, permissions chmod 600) to avoid typing passwords every time. Or use pg_service.conf for named connection profiles.
The psql Prompt
When connected, you see a prompt like:
myapp=#
The # means you are a superuser. Regular users see =>. The database name before the prompt tells you which database you are connected to.
If a query spans multiple lines, the prompt changes:
myapp=# SELECT
myapp-# name, -- still collecting input
myapp-# salary
myapp-# FROM employees;
Press q to exit a result pager, and \q to quit psql entirely.
Essential Meta-Commands
Meta-commands start with a backslash \ and are processed by psql itself (not sent to the server).
Database and Connection Info
\l -- list all databases
\l+ -- list databases with size info
\c dbname -- connect (switch) to a different database
\conninfo -- show current connection details
myapp=# \conninfo
You are connected to database "myapp" as user "postgres" via socket in "/var/run/postgresql" at port "5432".
Schema Inspection
\dt -- list tables in current schema
\dt *.* -- list all tables in all schemas
\dt public.* -- list tables in public schema
\d tablename -- describe a table (columns, types, indexes, constraints)
\d+ tablename -- more detail (storage, comments)
\dv -- list views
\dm -- list materialized views
\df -- list functions
\df+ funcname -- details about a specific function
\dn -- list schemas
\du -- list users (roles)
\dp tablename -- show privileges on a table
Example: \d employees
myapp=# \d employees
Table "public.employees"
Column | Type | Nullable | Default
-------------+-----------------------------+----------+--------------------
id | integer | not null | nextval('emp_id_seq')
name | text | not null |
dept | text | |
salary | numeric(10,2) | |
hire_date | date | |
created_at | timestamp with time zone | | now()
Indexes:
"employees_pkey" PRIMARY KEY, btree (id)
"employees_name_idx" btree (name)
Running Queries and Scripts
\i /path/to/file.sql -- execute a SQL file
\ir relative/path.sql -- execute relative to current script
\e -- open current query buffer in $EDITOR
\ef funcname -- edit a function in $EDITOR
\ev viewname -- edit a view in $EDITOR
# Run a SQL file from the command line (no interactive session)
psql -U postgres -d myapp -f schema.sql
# Run a single command and exit
psql -U postgres -d myapp -c "SELECT COUNT(*) FROM employees;"
Output Formatting
\x -- toggle expanded display (vertical layout for wide rows)
\x auto -- auto-switch to expanded when rows are wide
\t -- toggle tuples-only (hides column headers and row count)
\a -- toggle aligned/unaligned output
\pset border 2 -- add borders to output table
\H -- toggle HTML output mode
\o file.txt -- send output to a file
\o -- stop sending to file (back to terminal)
Normal output:
id | name | salary
----+-------+--------
1 | Alice | 60000
2 | Bob | 85000
After \x (expanded display):
-[ RECORD 1 ]------
id | 1
name | Alice
salary | 60000
-[ RECORD 2 ]------
id | 2
name | Bob
salary | 85000
Expanded display is invaluable for tables with many columns.
Timing
\timing -- toggle query timing
\timing on -- always show timing
myapp=# \timing on
Timing is on.
myapp=# SELECT COUNT(*) FROM orders;
count
-------
92451
(1 row)
Time: 12.345 ms
Copying Data
-- Export a table to CSV
\copy employees TO '/tmp/employees.csv' CSV HEADER;
-- Import from CSV
\copy employees FROM '/tmp/employees.csv' CSV HEADER;
-- Export a query result
\copy (SELECT id, name FROM employees WHERE dept = 'IT') TO '/tmp/it_team.csv' CSV HEADER;
\copy (backslash copy) runs on the client side and reads/writes files on your local machine. COPY (without backslash) is a server-side command that reads/writes files on the server — it requires superuser privileges and access to the server filesystem.
Variables and Scripting
-- Set a variable
\set myvar 'IT'
-- Use it in a query (note: no space between : and the variable name)
SELECT * FROM employees WHERE dept = :'myvar';
-- Set a numeric variable
\set limit_rows 10
SELECT * FROM orders LIMIT :limit_rows;
Help
\? -- list all psql meta-commands
\h -- list all SQL commands
\h SELECT -- show syntax help for SELECT
Setting Up ~/.psqlrc
The ~/.psqlrc file runs automatically every time you start psql. Use it to set your preferred defaults:
-- ~/.psqlrc
-- Always show timing
\timing on
-- Auto-expand wide results
\x auto
-- Set a nice prompt: show user@host:db
\set PROMPT1 '%n@%m:%/%R%# '
-- Show null values explicitly
\pset null '(null)'
-- Don't show welcome banner
\set QUIET 1
-- Useful abbreviations
\set version 'SELECT version();'
\set activity 'SELECT pid, state, wait_event_type, wait_event, query FROM pg_stat_activity;'
After saving, run \i ~/.psqlrc or simply restart psql to apply the settings.
Searching History
psql keeps a history of commands (stored in ~/.psql_history). Use:
- Up/Down arrows — cycle through history
- Ctrl+R — reverse search through history (like bash)
- Ctrl+A — go to beginning of line
- Ctrl+E — go to end of line
Quick Reference Card
| Command | What it does |
|---|---|
\l |
List databases |
\c dbname |
Switch database |
\dt |
List tables |
\d table |
Describe table |
\du |
List users/roles |
\df |
List functions |
\dn |
List schemas |
\timing |
Toggle query timing |
\x |
Toggle expanded display |
\i file.sql |
Run a SQL file |
\copy ... TO/FROM |
Import/export CSV |
\e |
Open editor |
\q |
Quit psql |
\? |
Help on meta-commands |
\h CMD |
Help on SQL command |
\watch N to re-run the last query every N seconds — great for monitoring long-running operations: SELECT pid, state, query FROM pg_stat_activity; \watch 2