Right, let’s talk about the real reason you’re here: the meta-commands. These are the magic spells that make psql so much more than just a dumb SQL terminal. They’re the shortcuts, the sanity checks, the “oh thank god I don’t have to query the system catalogs manually again” lifesavers.

Forget the clunky information_schema queries for a moment. These commands are psql’s love letter to the DBA and developer who values their time. They all start with a backslash (\), which is your signal to psql that you’re not talking standard SQL; you’re talking its native language.

The Family of \d: Your Schema Investigation Squad

The \d command is the workhorse, but it’s not a lone operator. It’s the head of a whole family. Typing just \d by itself is like asking “what’s in this schema?” and it will show you a list of all relations—which is Postgres-speak for tables, views, indexes, sequences, and materialized views. It’s your first stop when you’re poking around an unfamiliar database.

But the real power is in its specific forms. Let’s get tactical.

-- Show all tables in the current schema. Perfect for a quick overview.
\dt

-- Show all indexes. Crucial for debugging performance or checking if your fancy new index actually got created.
\di

-- Show all functions. This is a lifesaver when you can't remember if that function is named 'calculate_score' or 'score_calculate'.
\df

-- Want to see sequences? Maybe you're neck-deep in some serial column weirdness.
\ds

-- And views, because sometimes you forget which of your "tables" is actually a clever (or terrible) view.
\dv

Here’s the first “questionable choice” to call out: the default behavior. If you just type \dt, it only shows tables in your current search_path. If a table exists in a different schema, it’s invisible. This has tripped me up more times than I care to admit. You have to be explicit:

-- Show tables in a specific schema (e.g., 'auth')
\dt auth.*

-- Show all tables in ALL schemas you have access to
\dt *.*

The Devil’s in the Details (and the Permissions)

Now, let’s say you found a table with \dt. The next move is almost always \d table_name. This is the command’s killer feature. It gives you the full autopsy: the columns with their types, defaults, and nullability; indexes; foreign keys; check constraints; the whole shebang.

But a pitfall awaits the unwary: permissions. \d shows you what you are allowed to see. If you don’t have permissions on a sequence used by a serial column, it won’t show up. If you can’t read a table, it won’t appear in \dt. This isn’t a bug; it’s a security feature. It just means that when your \d output looks sparse, your first troubleshooting step should be to question your role’s privileges, not the sanity of the database designer.

Listing Databases and Getting Help

Before you even connect to a specific database, you might need to see what’s available on the cluster. That’s what \l is for. It’s your directory of databases. The + flag is a best practice you should adopt immediately—it adds a “Description” column and shows access privileges, which is infinitely more useful.

-- The good way to do it
\l+

And when you inevitably forget the exact name of a command or wonder what \df actually accepts as arguments, you don’t go to some external webpage. You use \?. This is the in-terminal cheat sheet. It’s brilliantly comprehensive. Typing \? is like admitting, “I know the tool has the answer, I just forgot the exact incantation,” which is the mark of a true professional, not a novice.

Formatting: Making the Output Less of an Eyesore

The default output format for \d and friends is “aligned,” which is fine until your query returns a few hundred rows and the columns are wider than your screen. Then it becomes a word-wrapped mess that’s utterly unreadable.

This is where the designers gave us an escape hatch. You can switch modes on the fly.

-- Switch to 'unaligned' mode, which uses a delimiter (like a CSV). Great for piping data into another tool.
\a

-- While you're at it, tell it to use a real delimiter. Commas are classic for a reason.
\pset fieldsep ','

-- Or, switch to 'expanded' mode. This displays each row as a set of key-value pairs, one per line.
\x
-- You can toggle this. It's fantastic for wide rows with many columns where you want to see everything clearly.

The best practice? Don’t just suffer with the defaults. Use \x auto. This is psql being genuinely clever. It will automatically switch to expanded mode if the output row is too wide for your terminal, and back to normal otherwise. It’s the set-it-and-forget-it solution.

-- Do this once per session and thank me later.
\pset format wrapped
\x auto

These commands are your flashlight and multi-tool as you navigate the dark, twisty corridors of your database. Use them liberally. They exist precisely so you can spend less time remembering obscure catalog column names and more time actually building things.