pspg: a table-aware pager for psql that freezes columns, sorts by number and also reads CSV, with no native Windows build
Unix pager (with very rich functionality) designed for work with tables. Designed for PostgreSQL, but MySQL is supported too. Works well with pgcli too. Can be used as CSV or TSV viewer too. It supports searching, selecting rows, columns, or block and export selected area to clipboard.
At a glance
- What is it?
- okbob/pspg is a C pager written to replace less for psql output. It understands table layout, so it can freeze rows and columns, sort by a numeric column, copy a selected block and read CSV or TSV, but it needs WSL2 on Windows and leans on a long list of command line switches.
- Who is it for?
- Use pspg if you read wide query results in psql, pgcli or mysql every day and want frozen columns, numeric sorting and block copy inside the pager. Skip it for native Windows work, since only WSL2 is supported, or for plain text paging where less is enough.
- Can I use it commercially?
- Yes. BSD-2-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.
Star history
- okbob/pspg2,744 ★ · +5
| Repository | 2026-10-04 | 2026-11-14 |
|---|---|---|
| okbob/pspg | 2.7k | 2.7k |
5 Stars in the last 41 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
less has no idea what a table is, and pspg was written for that gap
The author's reasoning is simple: everyone who uses psql also uses the less pager, which works well but has no special support for tabular data. He found a few projects and none was good enough, so he wrote a small specialised pager to use as a psql pager.
The stated targets show what less cannot do. pspg can freeze the first few rows or columns, sort data by a specified numeric column, use themes such as mcview or FoxPro, use the mouse, and copy a selected range to the clipboard.
The consequence is that pspg treats its input as a grid. When the content is not a table, its behaviour is less obviously useful, which is why the --only-for-tables switch exists: it uses the standard pager when the content is not a table. If you set pspg as your only pager for everything, that option is the one that stops it getting in the way of ordinary text.
Freezing has a limit worth knowing. The -c or --freezecols=N switch accepts N from 0 to 9, so you can pin at most nine columns. The look is adjustable too: -s sets a colour style number from 0 to 22, --line-numbers adds a line number column, --vertical-cursor shows a vertical column cursor, --highlight-odd-rec highlights odd records when the style supports it, and --null=STRING shows a chosen string instead of NULL. --hide-header-line removes the line between column names and data, and --double-header makes the header separator use double lines.
PSQL_PAGER is the whole setup, and command line options beat the config file
Packages exist for the common systems:
# Debian (Ubuntu)
sudo apt-get install pspg
# RedHat (Fedora)
sudo dnf install pspgOn macOS with Homebrew the command is brew install pspg. Basic configuration is then a single environment variable:
export PSQL_PAGER='pspg'Common options can ride along, for example `export PSQL_PAGER='pspg -X -b'`, where -b means the black and white theme and -X preserves content after exit.
The warning to remember concerns precedence. Options on the command line have higher priority than options in the configuration file ~/.pspgconf. So a theme you set in the file will be overridden by a flag inside PSQL_PAGER, and the reverse will not happen. When your pager looks wrong, check the variable first, not the file.
Windows works only through WSL2, and the menu is a compile-time choice
Native installation on MS Windows is not supported. pspg works well inside wsl2, where installation is the same as on whichever Linux system you run there. That is a hard line for anyone whose psql runs in a native Windows terminal, because the pager has to live on the same side as the terminal that calls it.
Building from source is possible through autogen.sh, configure.ac, a Makefile and meson.build. The Makefile includes config.make from the configure script, and it compiles the objects csv.o, print.o, commands.o, unicode.o, themes.o, pspg.o, config.o, sort.o, pgclient.o and others. A second group, st_menu.o, st_menu_styles.o and menu.o, is added only when COMPILE_MENU is defined.
So the top menu bar is optional at build time. A distribution package may or may not include it, and the --menu-always switch only matters when it does. The repository also carries PDCurses.md for the curses layer.
Many database clients can use it, but pgcli needs a fix flag
Beyond psql, the pager is listed as usable from mysql, sqlite, pgcli, monetdb, Trino (formerly Presto SQL), usql, sqlcl for Oracle and nushell. The description adds that it works well with pgcli and that MySQL is supported too.
The options list has one switch aimed at a specific client: --pgcli-fix tries to fix some pgcli related issues. It is not on by default, so if pgcli output renders oddly, that is the first thing to add.
The cost of this breadth is that each client emits tables in its own format, and pspg has to detect the layout. Border style is set with --border from 0 to 2, and --force-uniborder replaces ASCII borders with Unicode ones. Records with a wrong number of columns are dropped when you use --ignore-short-rows, which is useful for messy output but silently removes rows, so use it knowingly.
CSV, TSV and streaming turn it into a general table viewer
The description says it can serve as a CSV or TSV viewer. The input switches are --csv and --tsv, with --csv-separator for the field character, --csv-header [on/off] to specify header line usage, and --skip-columns-like with a space separated string list, which ignores columns whose names contain a substring.
Two trim switches shorten data: --csv-trim-width=NUM trims a value after NUM characters and --csv-trim-rows=NUM trims after NUM rows. Both discard data in the view, so do not read a trimmed value as the real one.
For live data there are --stream, which reads input forever, and --querystream, which reads queries from a stream forever. Watch mode uses -q with a query and -w with a time in seconds to repeat the query or the file read. Connection flags -d, -h, -p, -U and -W are present, with defaults of a local socket and port 5432. --ni sets not interactive mode, and the note says it applies only to csv and query input.
Clipboard, mouse and exit behaviour depend on your terminal
Several switches exist because terminals differ. --clipboard-app=NUM chooses the app used for copy to clipboard, with values 1, 2, 3 or 4. The numbers are not mapped to names in the options text, so you find the working one by trial.
Mouse handling can be turned off with --no-mouse, and --no_xterm_mouse_mode disables the optional xterm mouse mode. --esc-delay=NUM sets the escape delay in milliseconds, where -1 is infinite and 0 means not used. --no-sleep removes waits introduced against flickering.
What happens on exit also has options. -X reprints content, and --on-exit-reset, --on-exit-clean, --on-exit-erase-line and --on-exit-sgr0 each send a specific terminal sequence. -F quits if the content fits on one screen, and --quit-on-f3 exits on F3 like mc viewers.
The practical consequence: if copy does nothing or the screen is left messy after quitting, the fix is almost always one of these switches, not a bug report.
Searching has its own switches. -i ignores case in searches that contain no uppercase, -I ignores case in all searches, and -g and -G stop line highlighting for searches. --no-last-row-search stops a new search from reusing the last pattern, and --no-sigint-search-reset keeps a search when you press CTRL C, while --on-sigint-exit makes CTRL C or Escape leave the program. Loading has switches as well: --no-progressive-load turns off progressive data load, --no-watch-file stops watching file changes through inotify, and --ignore_file_suffix stops pspg from deducing the format from a file suffix.
Releases arrive in bursts, and the last two came within two weeks
The three most recent releases are 5.8.16 on 2026-02-18, 5.9.0 on 2026-10-22 and 5.9.1 on 2026-11-02, and the last push was also on 2026-11-02. So there was a gap of about eight months between 5.8.16 and 5.9.0, followed by a quick patch release. The repository is not archived and is licensed BSD-2-Clause.
That pattern argues for checking your distribution's packaged version. A Debian or Fedora package may trail the newest tag, so features named in the newest switches, such as --stream or --pgcli-fix, are worth confirming with pspg --help and pspg --version on your own machine. The --info switch shows information about libraries and system, which helps when reporting a problem.
Other files worth knowing are SECURITY.md, a ToDo file, a tests directory, a pspg.1 man page, a bash-completion.sh script and a pspg.spec for RPM packaging.
Editorial conclusion
Use pspg if you read wide query results in psql, pgcli or mysql every day and want frozen columns, numeric sorting and block copy inside the pager. Skip it for native Windows work, since only WSL2 is supported, or for plain text paging where less is enough. Before relying on clipboard copy, test which --clipboard-app number works in your terminal.
Frequently asked questions
How do I use pspg with psql?
Set the environment variable PSQL_PAGER, for example export PSQL_PAGER='pspg', or add options such as -X and -b. Command line options override ~/.pspgconf.
Does pspg run natively on Windows?
No. Native installation on MS Windows is not supported, but pspg works well inside WSL2, where you install it as you would on the Linux system you use there.
Can pspg open a CSV or TSV file?
Yes. Use --csv or --tsv, with --csv-separator for the field character and --csv-header to set header line usage.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/okbob-pspg)Star history chart for your README
[](https://hysenlabs.com/projects/okbob-pspg)Was this useful?