pgterm README

The project's README from github.com/pgrundev/pgterm. As one markdown file: README.md.

pgterm

htop for all your Postgres databases — an interactive terminal UI that monitors every database you care about in one place, powered by pgbot's read-only diagnostics.

 pgterm   ▸ production  PROD                                                                        ^K commands  ? help
 DATABASES               │  1 Overview   2 PgBot   3 SQL   4 Data   5 Branches                 ! PostgreSQL 17 · 0s ago
                         │──────────────────────────────────────────────────────────────────────────────────────────────
  ! production      PROD │ production  PROD                                                        r refresh   2 pgbot
    2 indexes with zero  │ ● Connected · PostgreSQL 17.4 · RDS · up 10d · checked 0s ago
  ● staging      STAGING │
    checked 0s ago       │ ┌ PostgreSQL ─┐ ┌ Connections ┐ ┌ Active ─────┐ ┌ Size ───────┐ ┌ Uptime ─────┐
  ◌ analytics            │ │ 17.4        │ │ 84 / 300    │ │ 5           │ │ 140 GiB     │ │ 10d         │
    checking…            │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
 + Add database          │
                         │  cache hit  [████████████████████]  99.2%     ok
                         │  lock wait  [░░░░░░░░░░░░░░░░░░░░]  —         ok
                         │  rollbacks  [██░░░░░░░░░░░░░░░░░░]  12.0%     watch
                         │  idle idx   [███░░░░░░░░░░░░░░░░░]  20 GiB    review
                         │
                         │ PGBOT   3 findings need attention
                         │  ⚠ 2 indexes with zero scans in the observed window                        confidence MEDIUM
                         │  ⚠ 2 queries regressed vs baseline                                           confidence HIGH
                         │  ⚠ rollbacks 12% of transactions                                           confidence MEDIUM
                         │  ✓ Connections   84 / 300
                         │  ✓ Cache         99.2%
                         │  ✓ Locks         0 blocked
                         │  ✓ Vacuum        13d ago
                         │  ✓ Replication   210 ms

One row per database in the sidebar, badged by environment. pgterm checks them all in the background and flags the one that needs attention without stealing focus from the one you're looking at.

Five tabs per database: Overview answers "is this healthy" at a glance, PgBot has the full diagnostics, SQL runs a query, Data browses schemas and tables, and Branches lists the database's pgrun branches.

Below 100 columns the sidebar collapses to a tab strip and everything else stays put, so pgterm still works in a split pane.

Try it in 10 seconds (no database needed)

cargo build --release
./demo/run.sh

Three pretend databases — healthy, warnings, and a blocked-locks incident — served by a fake pgbot from the test fixtures. Everything works: the sidebar and its badges, both tabs, the gauges, the palette (:), the pgbot views, and the command bar (/ ask why did checkout get slower?). The demo keeps its config under $TMPDIR/pgterm-demo, so your real configuration is untouched.

Install

curl -fsSL https://raw.githubusercontent.com/pgrundev/pgterm/main/install.sh | sh

Downloads the latest release for your platform (linux/macOS, amd64/arm64), verifies its checksum, and installs to /usr/local/bin (override with PGTERM_INSTALL_DIR). pgterm drives pgbot — the diagnostic engine — so if pgbot isn't on your PATH the installer fetches it too, through pgbot's own checksum-verified installer (skip that with PGTERM_NO_PGBOT=1). https://pgterm.dev/install.sh works too (it redirects here — keep the -L flag).

Or with Homebrew on macOS or Linux — name both formulae, pgterm and the pgbot it drives, so Homebrew trusts both from the tap:

brew install pgrundev/tap/pgterm pgrundev/tap/pgbot

On Windows, in PowerShell (install pgbot separately from pgbot.dev):

irm https://pgterm.dev/install.ps1 | iex

Or build from source: cargo build --release.

Quickstart

One line installs pgterm, and pgbot with it when missing:

curl -fsSL https://raw.githubusercontent.com/pgrundev/pgterm/main/install.sh | sh

Point pgterm at your database and open it:

export DATABASE_URL='postgresql://user:password@host:5432/dbname'

pgterm add production   # validates the connection, then saves the profile
pgterm                  # opens the UI

add tests the connection before saving anything; a broken profile is never persisted.

Adding more databases

Give each database its own environment variable and reference it by name:

export STAGING_DATABASE_URL='postgresql://...'
export ANALYTICS_DATABASE_URL='postgresql://...'

pgterm add staging   --env STAGING_DATABASE_URL
pgterm add analytics --env ANALYTICS_DATABASE_URL --open   # --open jumps straight in

pgterm resolves variables when it starts — export first, then launch. To make a variable survive new terminals, add its export line to your shell profile (~/.zshrc or ~/.bashrc):

echo "export STAGING_DATABASE_URL='postgresql://...'" >> ~/.zshrc

pgterm list shows every profile and whether its variable is currently set.

Adding from inside the UI

Press a (or click + Add database). Name, then Stage (←/→ cycles auto · prod · staging · dev · local), then Connection, which accepts any of:

You type or paste What happens
STAGING_DATABASE_URL references the exported variable — persisted to config
postgresql://user:pass@host/db connects now, session-only, never saved
STAGING_DATABASE_URL='postgresql://...' connects now with the URL, saves only the name

Whatever you paste is masked on screen; connection strings never touch disk.

Security posture

Commands

Command What it does
pgterm Open the terminal UI
pgterm add <name> Add the database from DATABASE_URL (validates first)
pgterm add <name> --env <VAR> Add a database by env-var reference
pgterm add <name> --stage prod Add with an environment badge
pgterm add <name> --env <VAR> --open Add, then open the UI on it
pgterm list List configured databases (names only, never values)
pgterm remove <name> Remove the local profile (PostgreSQL untouched)
pgterm --interval 30s Background check cadence (default 60s)
pgterm --no-monitor Disable background checks
pgterm --default-config Print an annotated default config

Keys

NAVIGATION
Tab / S-Tab        focus sidebar / main pane
[                  previous database
]                  next database
1                  overview tab
2                  pgbot tab
3                  sql tab
4                  data tab
5                  branches tab
C-k / :            command palette
/                  command bar (verbs, ask …)
a                  add database
r                  refresh
j / Down           scroll down / move down
k / Up             scroll up / move up

SIDEBAR
Enter              open the selected database

OVERVIEW
Enter              open pgbot findings

SQL TAB
F5                 run the query (Ctrl-Enter too)

DATA TAB
Enter              open the schema, table, or rows
Esc                back up one level

BRANCHES TAB
Enter              open the branch as a tab

PGBOT TAB
Left / h           previous pgbot view
Right / l          next pgbot view

GENERAL
q                  quit
?                  help

? shows this same list inside pgterm — it is generated from the keymap, so it can never describe a binding that does not exist. A test checks this table against it too.

What moved in 0.2

The Overview tab

Six tiles, then the same four gauges pgbot's own inspect shows, computed from the same JSON by the same rules so the two never disagree:

Gauge What it measures When it is not shown
cache hit sampled cache-hit ratio; low when pgbot flags it thin sample below 10,000 blocks
lock wait sessions blocked right now not measurable without lock data
rollbacks rolled-back share of transactions; watch when flagged not measurable without the counter
idle idx bytes in zero-scan indexes, as a share of the database window < 15m in a cold stats window

Under them, the findings that need attention with pgbot's own confidence, then a ✓ line per subsystem that came back clean. Press Enter (or 2) for the full report.

SQL and Data

The SQL tab runs a query against the database and shows the rows. The Data tab browses schemas, then tables with size and row estimates, then a page of rows.

Both use pgterm's own connection, and both are fenced:

[[databases]]
name = "staging"
env = "STAGING_DATABASE_URL"
writes = true    # lift READ ONLY for this database only

TLS follows the connection string's own sslmode; pgterm never weakens it. Nothing you type is written to disk.

Branches

When a database has a pgrun project, its branches appear in the sidebar and on the Branches tab:

[[databases]]
name = "production"
env = "PROD_DATABASE_URL"
pgrun_project = "acme-api"   # `pgrun project list` shows your projects

Enter on a branch opens it as its own tab. The connection URL comes from pgrun at that moment, lives in memory for the session, and is never written to config — the tab is gone when you quit. Creating and deleting branches stays in the pgrun CLI, where the confirmations already live.

Needs pgrun on your PATH (or PGRUN_BIN), logged in. Without it the tab says so instead of failing.

Mouse

Clicking works on the sidebar, the tabs, the pgbot sub-tabs, the palette, and the rows of the Data and Branches tabs. Whatever the pointer is over is underlined, so you can tell what will respond before you click.

pgterm also asks the terminal for a hand pointer over those things, using OSC 22. That lands in Ghostty, kitty, WezTerm, foot and xterm; other terminals (including VS Code's) parse the sequence and discard it, so nothing is lost and nothing is printed. The underline is the part that works everywhere. Turn the request off with:

[ui]
pointer = false

pgterm always hands the pointer back on the way out, including after a panic.

Stages and badges

Each database carries an environment badge — PROD, STAGING, DEV, LOCAL — shown in the sidebar and the header. Set it explicitly, or let pgterm infer it from the name:

pgterm add production --env PROD_DATABASE_URL --stage prod

Without --stage, a name containing prod, stag, local or dev picks its own badge; anything else gets none. The badge is a word first, so it survives a monochrome terminal.

Configuration

~/.config/pgterm/config.toml (or $XDG_CONFIG_HOME/pgterm/config.toml). pgterm --default-config prints an annotated copy of the defaults:

version = 1

[settings]
interval_seconds = 60
max_concurrent_checks = 3

[ui]
sidebar_detail = true   # a second, dim line per database in the sidebar
bell = false            # ring the terminal bell with a toast

[[databases]]
name = "production"
env = "PROD_DATABASE_URL"
stage = "prod"          # prod | staging | dev | local — inferred when absent

When a database you are not looking at turns critical or unavailable, a one-line toast appears at the right of the command bar for five seconds (and rings the bell if you asked for one). Nothing interrupts the database you are actually reading.

Building

cargo build --release   # → target/release/pgterm
cargo test

pgterm finds pgbot on PATH, or wherever PGBOT_BIN points.

License

Apache-2.0

pgterm (pgrundev/pgterm)

Searching Database…

350 ·GitHub
这是什么?pgterm 是一个交互式终端界面,把你关注的每个 Postgres 数据库集中在一处监控,底层使用 pgbot 的只读诊断。
它只是个监控面板,还是也能在里面执行查询?每个数据库有五个标签页:Overview(健康状态一目了然)、PgBot(完整诊断)、SQL(执行查询)、Data(浏览模式和表)以及 Branches(列出 pgrun 分支)。
怎么安装并让它连接到数据库?通过 release 安装脚本、Homebrew 或 'cargo build --release' 安装(Windows 上用 PowerShell 安装),然后带 DATABASE_URL 运行 'pgterm add'——它会在保存之前先测试连接。
它需要单独安装 pgbot 吗?pgterm 驱动的是一个独立诊断引擎 pgbot;如果 pgbot 还不在你的 PATH 中,pgterm 安装器会自动获取并校验它,除非你设置了 PGTERM_NO_PGBOT=1。
pgterm 真的能改动我的数据库吗?不能——它严格只读:除了白名单内的诊断外没有 SQL 控制台,也没有 shell,每条语句都在 READ ONLY 事务中运行,除非配置明确设置 writes = true。
它在 Windows 上也能运行吗,还是只有 macOS/Linux?它也可通过 PowerShell 安装器在 Windows 上运行(该平台需单独安装 pgbot),同时提供 amd64 和 arm64 的原生 linux/macOS 二进制。
我的连接字符串和密码最终会到哪里?它们绝不会落盘、进日志或显示在屏幕上——配置文件只存储环境变量名称,凭据通过子进程环境传递给 pgbot,绝不会出现在 argv 或 shell 历史中。
不连接真实数据库也能试用 pgterm 吗?可以——内置演示基于测试固件提供三个假数据库(健康、告警、锁阻塞),可以体验侧边栏、仪表、命令面板和 pgbot 视图,并使用 $TMPDIR 下的独立配置,不会影响你的真实配置。
Branches 标签页显示什么?它列出一个数据库的 pgrun 分支;打开某个分支会创建一个仅存在于会话中的标签页,其连接 URL 实时来自 pgrun,绝不会写入配置。
pgterm 如何判定数据库的环境标识?每个数据库都显示 PROD/STAGING/DEV/LOCAL 标识,可用 --stage 显式指定,或在名称包含 'prod'、'stag'、'local' 或 'dev' 时自动推断。
pgterm 支持鼠标点击吗?支持——侧边栏、标签页、pgbot 子标签、命令面板和表格行都可以点击,可悬停元素会加下划线,在支持的终端(如 Ghostty 和 kitty)中还会显示手型光标提示。
What are similar projects?pgbot, usql, tusk, sqlx, pgx, sampler, migrate, dbx
Creator
pgrundev
Size
0.6 MB
Stars
350
Age
1mo
Commits · 90 Days