Skip to content
Agentmart
Submit a tool

postgres-health-check

Read-only PostgreSQL instance health battery: connectivity/uptime, cache hit ratio, dead tuples & autovacuum hotspots, XID wraparound distance, long-running &…

Skill by fmflurry

IndexedMIT★ 171
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/fmflurry-postgres-health-check

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Read-only PostgreSQL instance health battery: connectivity/uptime, cache hit ratio, dead tuples & autovacuum hotspots, XID wraparound distance, long-running & idle-in-transaction sessions, unused indexes, checkpoint stats, archiver health, connection count vs max_connections, and docker container/volume checks. Use when asked about db health, postgres check, vacuum, bloat, wraparound, autovacuum, database slow, or connection count. Target: postgres:16-alpine (container gc-platform-postgres). Read alongside the postgres-dba agent.

Use cases: backend, devops, agent-building

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 26, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/postgres-health-check

What's inside

Skill name
postgres-health-check
Description
Read-only PostgreSQL instance health battery: connectivity/uptime, cache hit ratio, dead tuples & autovacuum hotspots, XID wraparound distance, long-running & idle-in-transaction sessions, unused indexes, checkpoint stats, archiver health, connection count vs max_connections, and docker container/volume checks. Use when asked about db health, postgres check, vacuum, bloat, wraparound, autovacuum, database slow, or connection count. Target: postgres:16-alpine (container gc-platform-postgres). Read alongside the postgres-dba agent.
License
MIT
Instructions
279 lines in SKILL.md · view on GitHub

Files (2)

  • SKILL.md
  • reference-migration-ops.md

SKILL.md (first lines)

# PostgreSQL Instance Health Check

**Target version:** `postgres:16-alpine` — this repository's `gc-platform-postgres` container (db `gcplatform`, owner role `gcplatform`, runtime role `gc_kourou_app_login`).

**Contract:** every check below is a read-only diagnostic (SELECT against `pg_stat_*`/`pg_catalog`, `pg_isready`, `docker` read commands). Each check gives: **query → interpretation → severity → remediation**. Remediations that mutate state are emitted ONLY as `⚠️ HUMAN CONFIRMATION REQUIRED` blocks — if `postgres-dba` is installed, that agent never executes them; otherwise `database-reviewer` or the main agent does not either.

**Connection:**

```bash
docker exec gc-platform-postgres psql -U gcplatform -d gcplatform -c "<query>"
```

**Progressive disclosure:** for the OPS side of applying EF Core migrations (lock windows at apply time, `CREATE INDEX CONCURRENTLY` vs the migration transaction, post-migration bloat/vacuum watch, live model-drift check), load `reference-migration-ops.md` in this skill's directory; code-side migration/schema correctness stays with `database-reviewer`.

---

## 1. Connectivity & uptime

```sql
SELECT version();
SELECT now() - pg_postmaster_start_time() AS uptime;
SELECT pg_is_in_recovery();
```

```bash
docker exec gc-platform-postgres pg_isready -U gcplatform -d gcplatform
```

**Interpretation:** `pg_isready` non-zero exit = server not accepting connections (CRITICAL). Very short uptime + no deploy = crash-loop (check `docker logs --tail 200 gc-platform-postgres`). `pg_is_in_recovery() = true` on the primary = unexpected (this stack has no replicas).

**Severity:** CRITICAL if unreachable; LOW note if uptime < 1h (statistics views were reset — treat other checks' counters cautiously).

---

## 2. Cache hit ratio

```sql
SELECT
  datname,
  blks_hit,
  blks_read,
  ROUND(blks_hit::numeric / NULLIF(blks_hit + blks_read, 0) * 100, 2) AS cache_hit_ratio_pct
FROM pg_stat_database
WHERE datname = current_database();
```

**Interpretation:** ratio = shared-buffer hits / (hits + disk reads). Healthy OLTP ≥ 99%. < 95% on a warm instance means working set exceeds `shared_buffers` (default 128MB here — no `command:` override in compose) or queries do large sequential scans. Stats accumulate since last reset — judge the trend, not a snapshot.

**Severity:** MEDIUM (< 95%), HIGH (< 90% with user-visible latency).

**Remediation:** size `shared_buffers` per the `postgres-performance-tuning` skill; first confirm with EXPLAIN that low ratio is not just batch analytics scans.

---

## 3. Dead tuples & autovacuum hotspots

```sql
SELECT
  schemaname, relname,
  n_live_tup, n_dead_tup,
  ROUND(n_dead_tup::numeric / NULLIF(n_live_tup + n_dead_tup, 0) * 100, 2) AS dead_pct,
  last_vacuum, last_autovacuum, last_analyze, last_autoanalyze,
  autovacuum_count
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC
LIMIT 20;
```

**Interpretation:** `n_dead_tup` grows with UPDATE/DELETE; autovacuum reclaims them. Hotspots: high `dead_pct` (> 20%) AND (`last_autovacuum` NULL or old) = autovacuum not keeping up (long transactions hold back the xmin horizon; check check 5). `n_dead_tup` is an *estimate* from the stats collector, not an exact count. Bloat also lives in indexes — compare `pg_total_relation_size` vs `pg_relation_size`.

**Severity:** HIGH (dead_pct > 50% on a hot table, or never autovacuumed); MEDIUM (20–50%).

**Remediation:**

⚠️ HUMAN CONFIRMATION REQUIRED

```sql
-- Reclaim space without the exclusive lock of VACUUM FULL (safe online):
VACUUM (ANALYZE, VERBOSE) <schema>.<table>;

-- For tables that bloat repeatedly, tighten per-table autovacuum:
ALTER TABLE <schema>.<table> SET (
  autovacuum_vacuum_scale_factor = 0.05,
  autovacuum_analyze_scale_factor = 0.02
);
```

`VACUUM FULL` rewrites the whole table under an `ACCESS EXCLUSIVE` lock — only as last resort, off-hours, with a fresh backup. Source: https://www.postgresql.org/docs/16/routine-vacuuming.html

---

## 4. XID wraparound distance

```sql
-- Per-database age:
SELECT datname, age(datfrozenxid) AS xid_age,
       ROUND(age(datfrozenxid)::numeric / 2147483647 * 100, 2) AS pct_to_wraparound
FROM pg_database WHERE datname = current_database();

-- Oldest per-table age (finds the table holding the horizon back):
SELECT schemaname, relname, age(relfrozenxid) AS rel_xid_age
FROM pg_stat_user_tables
ORDER BY age(relfrozenxid) DESC LIMIT 10;
```

**Interpretation:** transaction IDs are 32-bit; at age ≈ 2^31 (≈ 2.147 billion) the database **stops accepting writes** to prevent wraparound data loss. PostgreSQL warns when a database comes within **40 million** XIDs of wraparound and refuses new transactions when only **3 million** remain. Autovacuum normally prevents this (`autovacuum_freeze_max_age`, default 200M, triggers aggressive freeze vacuums) — except when autovacuum is blocked (long-lived transactions, stuck replication slots, `idle in transaction` sessions). Source: https://www.postgresql.org/docs/16/routine-vacuuming.html

**Severity:** CRITICAL (age > 2.1B, i.e. within 40M of wraparound); HIGH (> 1B); MEDIUM (> 500M — investigate why freeze vacuums lag).

**Remediation:**

⚠️ HUMAN CONFIRMATION REQUIRED

```sql
-- First remove whatever holds the xmin horizon back (check 5): kill the stuck session/slot.
-- Then database-wide freeze vacuum (I/O-heavy; run off-hours):
VACUUM (FREEZE, VERBOSE) <schema>.<table>;   -- per worst table
-- or, full database (long):
-- VACUUMFREEZE via: VACUUM (FREEZE); on each database

From fmflurry/settings-opencode, MIT.

More from fmflurry/settings-opencode

Signals

Stars
171
Forks
9
Open issues
0
Last commit (this folder)
Sep 19, 2026 (1 month ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

Same skill elsewhere

Copies of this SKILL.md published by others; search shows only one of them.

More from fmflurry

Cite this page

postgres-health-check skill. Agent Mart. https://agentmart.dev/skills/fmflurry-postgres-health-check (last updated 2026-10-24)