2026-07-05
You run SELECT * FROM users WHERE ... in psql, the result is 40 columns wide, less wraps every row into unreadable spaghetti, and the header disappears the moment you press space. So you type \pset pager off and squint at 200-line dumps like it's 1994. There is a better answer that predates every fashionable TUI: pspg, the "Postgres Pager" — despite the name it happily eats MySQL, SQLite, CSV, TSV, JSON-lines, and plain aligned text.
Install it (apt install pspg, brew install pspg, dnf install pspg) and wire it into psql:
cat >> ~/.psqlrc <<'EOF'
\pset border 2
\pset linestyle unicode
\setenv PAGER 'pspg --no-mouse -X -b'
EOF
Now every query lands in a pager that understands the table. The header row freezes. The first column freezes. Rows never wrap; you scroll horizontally with the arrow keys. Vim bindings work: / searches, n/N jump, g/G top/bottom, m sets a bookmark you can revisit with '.
Point it at anything tabular:
# CSV with a real header
pspg -f sales.csv --csv
# Tab-separated with custom delimiter
pspg -f logs.tsv --csv --csv-separator=$'\t'
# JSON lines from an API
curl -s https://api.example.com/events | pspg --querystream --format=json
# Live: watch a query result refresh every 2s
pspg --query='SELECT pid,state,query FROM pg_stat_activity' \
--host=db.internal --dbname=prod --watch 2
That last one is quietly amazing — pspg becomes a mini-dashboard, and you can freeze the view with p to inspect without the refresh yanking your cursor away.
Interactive superpowers most people never discover:
a (ascending) or d (descending) — pspg re-sorts in memory, no re-running the query.0-9 sets how many left columns stay pinned as you scroll right. Vital for wide fact tables.c then a substring jumps the horizontal scroll to the matching column. Great for SELECT * against 80-column tables.Alt-v highlights the current column so your eyes stop tracking the wrong number.Alt-k cycles ~20 built-in color themes. The Solarized ones are readable through a projector.Alt-l saves the current (possibly sorted, filtered) buffer to a file.Where does it beat the alternatives?
less -S: less has zero idea what a column is. No frozen header, no sort, no per-column search.mysql -e '...' | pspg Just Works with no plugin, no wrapper, no editor.One trick worth stealing: set it as the pager for mycli, litecli, and even kubectl get -o wide:
alias kwide='kubectl get pods -o wide | pspg --no-mouse -X -b --csv-header=on'
Suddenly a 20-node pod listing is navigable instead of terminal soup.
