Currently viewing the human version
Switch to AI version

What is psql?

psql is what you use when the fancy GUI tools decide to take a coffee break. It's PostgreSQL's command-line interface - ugly as hell but gets the job done when everything else fails.

The tool connects to PostgreSQL databases and lets you run SQL queries plus a bunch of meta-commands that start with backslashes. These meta-commands are lifesavers once you memorize them, but expect to Google "\dt vs \d+ vs \dn" about 47 times in your first week.

Why You'll End Up Using It

GUI tools like pgAdmin are pretty until they crash during a production incident and you're stuck with psql anyway. When your DataGrip license expires or TablePlus decides to freeze on a 10GB query result, psql is there looking smug as fuck.

Connection strings look like someone's password manager exploded:

psql \"postgresql://username:password@hostname:5432/database?sslmode=require\"

Save them in .pgpass or you'll never remember the syntax. Trust me on this one - I've wasted 2 hours debugging connection issues that turned out to be a missing ? in the connection string.

The Meta-Commands That Actually Matter

PostgreSQL Process Architecture

Skip the 80+ meta-commands bullshit. Here are the 10 you'll actually use:

  • `\l` - List databases (prepare for a wall of text)
  • `\c database_name` - Switch databases (finally)
  • `\dt` - Show tables (add + if you hate yourself and want to wait forever)
  • `\d table_name` - Describe table (the only way to see column types without writing SQL)
  • `\x` - Toggle expanded mode (lifesaver for wide tables, annoying for small ones)
  • `\q` - Quit (most important command)

Pro tip: \dt without a pattern on a large database will list 400+ tables and you'll regret it. Use `\dt pattern*` unless you enjoy scrolling.

PostgreSQL 18 and What Actually Changed

With PostgreSQL 18 released on September 26, 2025, you get async I/O improvements that can speed things up 3x in certain scenarios. The UUIDv7 functions are actually useful unlike the marketing promises.

The big win is JSON_TABLE support - finally, you can query JSON without writing nested bullshit that breaks your brain. Plus logical replication improvements that might actually work without mysteriously failing at 2am.

But here's the thing - if you're still on PostgreSQL 12 because your ops team is afraid of upgrades, none of this matters. psql works the same frustrating way it always has, which is both a blessing and a curse.

Now, before you ask "why not just use mysql or another database CLI tool?" - let's see how psql stacks up against the competition.

psql vs Other Database CLI Tools

Feature

psql (PostgreSQL)

mysql (MySQL/MariaDB)

sqlite3 (SQLite)

sqlcmd (SQL Server)

Meta-Commands

Extensive \ commands

Limited \ commands

. dot commands

Limited shortcuts

Auto-completion

Tables, columns, keywords

Basic completion

Basic completion

Limited

Output Formats

12+ formats (HTML, CSV, JSON)

Limited formats

CSV, HTML, JSON

Limited formats

Scripting Support

Variables, conditionals, loops

Basic variables

Limited scripting

Variables, conditions

Connection Options

SSL, multiple methods

SSL support

File-based only

Windows Auth, SSL

History

Full command history

Command history

Command history

Limited history

Syntax Highlighting

No (see pgcli)

No

No

No

Cross-platform

Yes (all major OS)

Yes

Yes

Windows primarily

File Operations

\i, \o, \copy

source, \T

.read, .output

:r, :out

Transaction Control

Full autocommit control

Autocommit control

Autocommit control

Transaction support

Explain Integration

\x expanded mode

Limited

Limited

Limited

The Shit You Actually Need to Know About psql

PostgreSQL Architecture

Commands That Don't Suck

The meta-command system turns SELECT * FROM information_schema.tables into \dt. Once you memorize them, you'll wonder how you survived without them. Until then, you'll Google the same commands daily.

The Commands You'll Use Every Day:

  • \l - List databases (brace yourself for the spam)
  • \c database_name - Switch databases without reconnecting
  • \dn - Show schemas (useful when someone creates 47 schemas)
  • \dt - Show tables (will murder your terminal on large DBs)
  • \d table_name - Describe table structure (lifesaver for forgotten column names)

When Things Go Wrong:

Output Formatting That Doesn't Hurt Your Eyes

The default output looks like ass. Here's how to fix it:

Real talk: Use `\x auto` instead of \x. It only expands tables that actually need it instead of making everything look like shit.

File Operations for When You're Not Completely Fucked

PostgreSQL Table Structure

The `\copy` command works without server file access, unlike `COPY` which will fail with permission errors that make you question your life choices:

-- Export that works from any client
\copy (SELECT * FROM users WHERE created_at > '2025-01-01') TO 'recent_users.csv' CSV HEADER

-- Import without dealing with server filesystem bullshit
\copy temp_table FROM 'data.csv' CSV HEADER

Gotcha alert: `\copy` and `COPY` are different. COPY runs on the server and needs file permissions. \copy runs on the client and just works. Learn this now or waste 2 hours later.

Connection Strings From Hell

SSL connections look like someone's regex nightmare:

## SSL with certificates (because security theater)
psql \"sslmode=require sslcert=client.crt sslkey=client.key host=db.example.com dbname=production user=readonly\"

## The connection string that actually works in production
export PGPASSWORD='your_password_here'
psql -h db.example.com -U readonly -d production

Save connection info in ~/.pgpass with format: hostname:port:database:username:password. Read about environment variables for easier connection management.

Production Debugging Commands

PostgreSQL Performance Dashboard

When shit hits the fan at 3am and your pager is going nuts:

-- See what's actually running (and killing your DB)
SELECT pid, usename, application_name, state, query_start,
       NOW() - query_start AS duration, query
FROM pg_stat_activity
WHERE state = 'active' AND query_start < NOW() - INTERVAL '30 seconds'
ORDER BY query_start;

-- Find the table that's eating all your disk space (saved my ass during a runaway log table incident)
SELECT schemaname, tablename,
       pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) as size,
       pg_size_pretty(pg_relation_size(schemaname||'.'||tablename)) as table_size,
       pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename) - pg_relation_size(schemaname||'.'||tablename)) as index_size
FROM pg_tables
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC LIMIT 10;

-- See blocked queries (when everything is hanging and users are screaming)
SELECT blocked_locks.pid AS blocked_pid,
       blocked_activity.usename AS blocked_user,
       blocking_locks.pid AS blocking_pid,
       blocking_activity.usename AS blocking_user,
       blocked_activity.query AS blocked_statement,
       blocking_activity.query AS blocking_statement
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
JOIN pg_catalog.pg_locks blocking_locks ON (blocking_locks.locktype = blocked_locks.locktype AND blocking_locks.granted = true)
JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
WHERE NOT blocked_locks.granted;

-- Nuclear option: Kill that runaway query (use with extreme prejudice)
SELECT pg_terminate_backend(12345); -- Replace 12345 with the actual PID

Real talk: I once spent 4 hours tracking down a "connection leak" that turned out to be a single query with a missing WHERE clause scanning 50M rows. Always run iming on so you know when your query takes 45 seconds instead of the expected 2ms.

Don't use pg_cancel_backend() - it's polite and slow. Use pg_terminate_backend() when you need that query dead immediately. PostgreSQL's system catalogs are your friend when everything is on fire.

FAQ: The Questions Everyone Googles

Q

How do I connect to a PostgreSQL database using psql?

A

Hit psql -h hostname -p port -U username -d database_name. For local connections: psql -U postgres -d mydb. It'll ask for your password unless you set up .pgpass, which you absolutely should because typing passwords is for masochists.

Q

What's the difference between psql commands and SQL commands?

A

SQL commands end with semicolons and actually hit the database. Meta-commands start with \\ and psql handles them locally. Forget the semicolon and psql will mock you with -# until you add that damn semicolon.

Q

How do I exit psql?

A

Hit \\q to escape. Or mash Ctrl+D if you're feeling violent. Don't try exit

  • this isn't your shell.
Q

Can I run SQL scripts from files in psql?

A

\\i filename.sql runs scripts. Use \\ir if you're dealing with relative paths and don't want to think about directories. From command line: psql -f script.sql database_name.

Gotcha: Scripts that fail halfway through will leave your DB in a weird state. Wrap everything in transactions if you give a shit about data integrity.

Q

How do I format output for better readability?

A

\\x auto is your friend

  • only expands wide tables that actually need it. \\pset null 'NULL' shows NULL values instead of invisible spaces that'll fuck with your brain. \ iming on shows you how slow your queries really are.
Q

How do I see all tables in a database?

A

\\dt shows tables. Add *.* to see across all schemas: \\dt *.*. But warning: \\dt without a pattern on a database with 500+ tables will spam your terminal. Use \\dt pattern* unless you enjoy scrolling.

Q

What's the best way to export query results?

A
\copy (SELECT * FROM users WHERE active = true) TO 'active_users.csv' CSV HEADER

Use \\copy not COPY. COPY needs server file permissions and will shit the bed with "permission denied" errors. \\copy just works.

Q

How do I handle large result sets that scroll off screen?

A

The pager is usually on by default. If not: \\pset pager on. Press q to get back to psql when you're done scrolling. If you're stuck in pager hell, mash q until it lets you go.

Q

Can I use variables in psql scripts?

A
\set table_name users
\set min_id 1000
SELECT * FROM :table_name WHERE id > :min_id;

Works great for scripts. Variables persist until you \\unset them or your session dies.

Q

How do I connect to different databases without restarting psql?

A

\\c database_name switches databases instantly. No need to reconnect like a peasant. You can also specify user: \\c production readonly_user.

Q

What happens if I forget a semicolon?

A

PostgreSQL Error Message Example

psql shows -# and waits. Add the semicolon or hit \\r to reset and start over. This will happen approximately 47 times your first day.

Q

How do I get help within psql?

A

\\? for meta-commands, \\h for SQL help. \\h SELECT gives you syntax help. Most of it is useless but occasionally saves you a Google search.

Q

Can psql connect to multiple databases simultaneously?

A

Nope. One session, one database. Open multiple terminals like everyone else, or use \\c to hop around.

Q

How do I troubleshoot connection issues?

A

Common fuckups and the error messages you'll see:

"psql: FATAL: database 'mydb' does not exist"

  • Check database name spelling (case matters)
  • Use \\l to list actual databases after connecting to any DB

"psql: FATAL: role 'username' does not exist"

  • Wrong username or user hasn't been created
  • Try connecting as postgres user first

"psql: could not connect to server: Connection refused"

  • PostgreSQL isn't running (check systemctl status postgresql)
  • Wrong port (5432 is default, but Docker often uses random ports)
  • Wrong host (localhost vs 127.0.0.1 sometimes matters for auth config)

"psql: FATAL: no pg_hba.conf entry for host"

  • pg_hba.conf is rejecting your connection
  • Most common cause: trying to connect remotely when only localhost is allowed
  • Fix: Add appropriate entry to pg_hba.conf and reload config

"psql: FATAL: password authentication failed"

  • Wrong password (obviously)
  • User might require different auth method (peer, trust, md5)
  • Check if .pgpass file has wrong credentials

Use psql -v for verbose output when debugging. The error messages are actually helpful once you stop panicking and read them.

Q

Is there syntax highlighting available in psql?

A

pgcli with syntax highlighting

Standard psql is ugly as sin. pgcli has syntax highlighting and better autocompletion, but it's one more thing to install. Your call - pretty colors vs one less dependency.

Now that you're armed with the essential knowledge and troubleshooting tips, here are the resources you'll actually want to bookmark for when shit inevitably goes sideways.

Resources That Don't Suck

Related Tools & Recommendations

tool
Similar content

pgAdmin - The GUI You Get With PostgreSQL

It's what you use when you don't want to remember psql commands

pgAdmin
/tool/pgadmin/overview
100%
tool
Similar content

pgcli - psql That Doesn't Suck

Explore pgcli, the enhanced PostgreSQL command-line interface. Learn why it exists, how to install it, and get answers to common FAQs about its features and usa

pgcli
/tool/pgcli/overview
86%
tool
Similar content

usql - One Database Client to Rule Them All (Mostly)

The universal database client that actually works - PostgreSQL, MySQL, Oracle, SQLite, and 40+ more databases

usql
/tool/usql/overview
77%
tool
Recommended

CloudBeaver - DBeaver in Your Browser

Getting tired of being the only one who can check the database when shit breaks at 2am

CloudBeaver
/tool/cloudbeaver/overview
49%
tool
Recommended

DBeaver Community - If You Work With Databases and Don't Want to Pay for DataGrip

Java-based database client that connects to basically anything with a JDBC driver - from MySQL to MongoDB to whatever the hell Oracle is calling their stuff thi

DBeaver Community
/tool/dbeaver/overview
49%
tool
Recommended

DBeaver Performance Optimization - Stop Waiting 30 Seconds for Your Database to Load

Real-world fixes for the most annoying DBeaver performance issues - from startup time that makes you question life choices to memory leaks that crash your lapto

DBeaver Community
/tool/dbeaver/performance-optimization
49%
compare
Recommended

PostgreSQL vs MySQL vs MongoDB vs Redis vs Cassandra - Enterprise Scaling Reality Check

When Your Database Needs to Handle Enterprise Load Without Breaking Your Team's Sanity

PostgreSQL
/compare/postgresql/mysql/mongodb/redis/cassandra/enterprise-scaling-reality-check
48%
compare
Recommended

PostgreSQL vs MySQL vs MongoDB vs Cassandra - Stop Overthinking Your Database Choice

The Real Engineering Decision: Which Database Won't Ruin Your Life

PostgreSQL
/compare/postgresql/mysql/mongodb/cassandra/database-architecture-performance-comparison
48%
integration
Recommended

FastAPI + SQLAlchemy + Alembic + PostgreSQL: The Real Integration Guide

integrates with FastAPI

FastAPI
/integration/fastapi-sqlalchemy-alembic-postgresql/complete-integration-stack
48%
tool
Similar content

Turso CLI Installation Guide - SQLite Without The Server Hell

SQLite that doesn't break when you actually need it to scale

Turso CLI
/tool/turso-cli/installation-guide
46%
tool
Recommended

DataGrip - Database IDE That Doesn't Completely Suck

Cross-platform database tool that actually works with multiple databases from one interface

DataGrip
/tool/datagrip/overview
44%
tool
Popular choice

jQuery - The Library That Won't Die

Explore jQuery's enduring legacy, its impact on web development, and the key changes in jQuery 4.0. Understand its relevance for new projects in 2025.

jQuery
/tool/jquery/overview
44%
howto
Similar content

How I Migrated Our MySQL Database to PostgreSQL (And Didn't Quit My Job)

Real migration guide from someone who's done this shit 5 times

MySQL
/howto/migrate-legacy-database-mysql-postgresql-2025/beginner-migration-guide
43%
tool
Popular choice

Hoppscotch - Open Source API Development Ecosystem

Fast API testing that won't crash every 20 minutes or eat half your RAM sending a GET request.

Hoppscotch
/tool/hoppscotch/overview
42%
tool
Popular choice

Stop Jira from Sucking: Performance Troubleshooting That Works

Frustrated with slow Jira Software? Learn step-by-step performance troubleshooting techniques to identify and fix common issues, optimize your instance, and boo

Jira Software
/tool/jira-software/performance-troubleshooting
40%
tool
Popular choice

Northflank - Deploy Stuff Without Kubernetes Nightmares

Discover Northflank, the deployment platform designed to simplify app hosting and development. Learn how it streamlines deployments, avoids Kubernetes complexit

Northflank
/tool/northflank/overview
38%
tool
Similar content

pgvector - Stop Paying Pinecone's Ridiculous Per-Query Fees

Just add vector search to your existing PostgreSQL database instead of paying something like $400/month for 10M queries (which becomes like $2k+ when you actual

pgvector
/tool/pgvector/overview
37%
tool
Similar content

PostgreSQL - The Database You Use When MySQL Isn't Enough

Explore PostgreSQL's advantages over other databases, dive into real-world production horror stories, solutions for common issues, and expert debugging tips.

PostgreSQL
/tool/postgresql/overview
37%
tool
Popular choice

LM Studio MCP Integration - Connect Your Local AI to Real Tools

Turn your offline model into an actual assistant that can do shit

LM Studio
/tool/lm-studio/mcp-integration
37%
alternatives
Similar content

PostgreSQL Alternatives: Escape Your Production Nightmare

When the "World's Most Advanced Open Source Database" Becomes Your Worst Enemy

PostgreSQL
/alternatives/postgresql/pain-point-solutions
36%

Recommendations combine user behavior, content similarity, research intelligence, and SEO optimization