postgresql — Claude Code skill: what it does, how to install
Guides PostgreSQL database administration, streaming replication, backups, and performance tuning. Useful when deploying or optimizing database instances.
npx skills add BagelHole/DevOps-Security-Agent-Skills --skill postgresql -a claude-codeWhat postgresql does
This skill provides runbooks and commands for administering PostgreSQL on Debian, Ubuntu, RHEL, or inside Docker Compose. It includes baseline user and database creation scripts alongside essential psql shortcuts. Pre-built SQL queries help track long-running transactions over 30 seconds, calculate table dead tuple bloat, inspect index scans, and check the cache hit ratio.
Performance tuning guidance covers memory allocation for shared_buffers, planner cost adjustments for SSDs, and logging slow queries via log_min_duration_statement. The guide also details client rules in pg_hba.conf, logical dumps with pg_dump, and physical backups using pg_basebackup. For streaming replication, it outlines setup steps on primary and standby nodes using standby.signal.
Package installation requires sudo or root privileges. Modifying shared_buffers or max_connections demands a full PostgreSQL restart, meaning pg_reload_conf() will not suffice for those changes.
What it helps with
- Configure streaming replication between primary and replica servers
- Tune memory settings including
shared_buffersandwork_meminpostgresql.conf - Detect active queries running longer than 30 seconds and table dead tuples
- Create database backups using
pg_dumporpg_basebackup - Secure client access in
pg_hba.confusingscram-sha-256
Example prompts for the agent
- Help me configure PostgreSQL streaming replication for a standby replica
- Optimize postgresql.conf for an SSD server and show queries for finding slow transactions
- Show commands to create a compressed database backup with pg_dump and restore it
How to install postgresql
1Skills CLI (Vercel)
npx skills add BagelHole/DevOps-Security-Agent-Skills --skill postgresql -a claude-code2Manually: put the files in place
~/.claude/skills/postgresql/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/postgresql/
1Skills CLI (Vercel)
npx skills add BagelHole/DevOps-Security-Agent-Skills --skill postgresql -a codex2Manually: put the files in place
.agents/skills/postgresql/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add BagelHole/DevOps-Security-Agent-Skills --skill postgresql -a cursor2Manually: put the files in place
.cursor/skills/postgresql/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install BagelHole/DevOps-Security-Agent-Skills postgresql2Manually: put the files in place
.github/skills/postgresql/SKILL.md1Skills CLI (Vercel)
npx skills add BagelHole/DevOps-Security-Agent-Skills --skill postgresql -a gemini-cli2Platform CLI
gemini skills install https://github.com/BagelHole/DevOps-Security-Agent-Skills --path infrastructure/databases/postgresqlManually: put the files in place
.devin/skills/postgresql/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add BagelHole/DevOps-Security-Agent-Skills --skill postgresql -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about postgresql
How to install postgresql in Claude Code?
Run npx skills add BagelHole/DevOps-Security-Agent-Skills --skill postgresql -a claude-code in your terminal.
What does the postgresql skill do?
It guides you through installing PostgreSQL on Linux or Docker, configuring streaming replication, tuning memory settings, and monitoring slow queries.
What are the prerequisites for this skill?
You need a Linux host (Debian, Ubuntu, or RHEL-based) or Docker, root or sudo privileges for package installation, and familiarity with basic SQL.
Source text
SKILL.md · MIT
---
name: postgresql
description: Administer PostgreSQL databases. Configure replication, backups, and performance tuning. Use when managing PostgreSQL deployments.
license: MIT
metadata:
author: devops-skills
version: "1.0"
---
# PostgreSQL
Administer, optimize, and secure PostgreSQL databases in development and production environments.
## When to Use
- You need a reliable, ACID-compliant relational database.
- Your application requires advanced features such as JSONB, full-text search, or CTEs.
- You are setting up streaming replication or point-in-time recovery.
- You need to tune an existing PostgreSQL deployment for better throughput.
## Prerequisites
- Linux server (Debian/Ubuntu or RHEL-based) or Docker.
- Root or sudo access for package installation.
- Familiarity with SQL fundamentals.
## Installation and Setup
```bash
# Debian / Ubuntu
sudo apt update
sudo apt install -y postgresql postgresql-contrib
# RHEL / Amazon Linux
sudo dnf install -y postgresql15-server postgresql15-contrib
sudo postgresql-setup --initdb
sudo systemctl enable --now postgresql
# Verify
psql --version
sudo systemctl status postgresql
```
## Initial User and Database Setup
```bash
# Switch to the postgres system user
sudo -u postgres psql
```
```sql
-- Create an application user
CREATE USER myapp WITH PASSWORD 'strong_password_here';
-- Create the database owned by that user
CREATE DATABASE mydb OWNER myapp;
-- Grant connection privileges
GRANT ALL PRIVILEGES ON DATABASE mydb TO myapp;
-- Connect to the database and set default privileges
\c mydb
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO myapp;
```
## psql Commands Reference
```
\l -- list databases
\dt -- list tables in current database
\d+ tablename -- describe table with storage info
\du -- list roles
\x -- toggle expanded output
\timing on -- show query execution time
\i file.sql -- execute SQL from file
\copy -- fast client-side COPY
```
## Configuration Tuning
Edit `/etc/postgresql/15/main/postgresql.conf` (path varies by OS and version).
```ini
# Connection settings
listen_addresses = '*'
max_connections = 200
# Memory — adjust to ~25% of total RAM for shared_buffers
shared_buffers = 4GB
effective_cache_size = 12GB
work_mem = 16MB
maintenance_work_mem = 512MB
# WAL / write performance
wal_buffers = 64MB
checkpoint_completion_target = 0.9
min_wal_size = 1GB
max_wal_size = 4GB
# Planner
random_page_cost = 1.1 # lower for SSD
effective_io_concurrency = 200 # for SSD
# Logging
log_min_duration_statement = 250 # log queries slower than 250 ms
log_checkpoints = on
log_connections = on
log_disconnections = on
log_lock_waits = on
```
```bash
# Reload configuration without restart
sudo -u postgres psql -c "SELECT pg_reload_conf();"
# Some settings (shared_buffers, max_connections) require a full restart
sudo systemctl restart postgresql
```
## pg_hba.conf — Client Authentication
```
# /etc/postgresql/15/main/pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD
local all postgres peer
host mydb myapp 10.0.0.0/8 scram-sha-256
host all all 0.0.0.0/0 reject
```
```bash
sudo systemctl reload postgresql
```
## Backup and Restore
### Logical Backups with pg_dump
```bash
# Plain SQL backup
pg_dump -U myapp -h localhost mydb > /backups/mydb_$(date +%F).sql
# Custom compressed format (recommended)
pg_dump -U myapp -h localhost -Fc mydb > /backups/mydb_$(date +%F).dump
# Backup a single table
pg_dump -U myapp -h localhost -t orders -Fc mydb > /backups/orders.dump
# Restore from custom format
pg_restore -U myapp -h localhost -d mydb --clean --if-exists /backups/mydb_2025-01-15.dump
# Restore plain SQL
psql -U myapp -h localhost -d mydb < /backups/mydb_2025-01-15.sql
```
### Physical Backups with pg_basebackup
```bash
# Full base backup (used for PITR and replica seeding)
pg_basebackup -h localhost -U replicator -D /backups/base_$(date +%F) \
--wal-method=stream --checkpoint=fast --progress --verbose
# Verify the backup
pg_verifybackup /backups/base_2025-01-15
```
## Streaming Replication
### Primary Server
```sql
-- Create replication user
CREATE USER replicator WITH REPLICATION LOGIN PASSWORD 'repl_secret';
```
```ini
# postgresql.conf on primary
wal_level = replica
max_wal_senders = 5
wal_keep_size = 1GB
```
```
# pg_hba.conf on primary
host replication replicator 10.0.0.0/8 scram-sha-256
```
### Replica Server
```bash
# Stop PostgreSQL on the replica
sudo systemctl stop postgresql
# Remove existing data directory
sudo rm -rf /var/lib/postgresql/15/main/*
# Base backup from primary
sudo -u postgres pg_basebackup \
-h 10.0.0.1 -U replicator \
-D /var/lib/postgresql/15/main \
--wal-method=stream --checkpoint=fast --progress
# Create standby signal file
sudo -u postgres touch /var/lib/postgresql/15/main/standby.signal
```
```ini
# postgresql.conf on replica
primary_conninfo = 'host=10.0.0.1 port=5432 user=replicator password=repl_secret'
hot_standby = on
```
```bash
sudo systemctl start postgresql
```
### Verify Replication
```sql
-- On primary
SELECT client_addr, state, sent_lsn, replay_lsn
FROM pg_stat_replication;
-- On replica
SELECT pg_is_in_recovery(); -- should return true
SELECT pg_last_wal_receive_lsn();
SELECT pg_last_wal_replay_lsn();
```
## Monitoring Queries
```sql
-- Active connections by state
SELECT state, COUNT(*)
FROM pg_stat_activity
GROUP BY state;
-- Long-running queries (> 30 seconds)
SELECT pid, now() - query_start AS duration, query
FROM pg_stat_activity
WHERE state = 'active'
AND now() - query_start > interval '30 seconds'
ORDER BY duration DESC;
-- Table bloat and dead tuples
SELECT relname,
n_live_tup,
n_dead_tup,
ROUND(n_dead_tup::numeric / GREATEST(n_live_tup, 1) * 100, 2) AS dead_pct
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC
LIMIT 10;
-- Index usage statistics
SELECT relname, indexrelname, idx_scan, idx_tup_read, idx_tup_fetch
FROM pg_stat_user_indexes
ORDER BY idx_scan ASC
LIMIT 10;
-- Cache hit ratio (should be > 99%)
SELECT ROUND(
100.0 * sum(blks_hit) / NULLIF(sum(blks_hit) + sum(blks_read), 0), 2
) AS cache_hit_pct
FROM pg_stat_database;
-- Database size
SELECT pg_database.datname,
pg_size_pretty(pg_database_size(pg_database.datname)) AS size
FROM pg_database
ORDER BY pg_database_size(pg_database.datname) DESC;
```
## Docker Compose Setup
```yaml
# docker-compose.yml
version: "3.9"
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
ports:
- "5432:5432"
environment:
POSTGRES_USER: myapp
POSTGRES_PASSWORD: secret
POSTGRES_DB: mydb
volumes:
- pg_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
command: >
postgres
-c shared_buffers=256MB
-c work_mem=8MB
-c maintenance_work_mem=128MB
-c effective_cache_size=768MB
-c log_min_duration_statement=250
healthcheck:
test: ["CMD-SHELL", "pg_isready -U myapp -d mydb"]
interval: 10s
timeout: 5s
retries: 5
pgbouncer:
image: edoburu/pgbouncer:latest
restart: unless-stopped
ports:
- "6432:6432"
environment:
DATABASE_URL: postgres://myapp:secret@postgres:5432/mydb
POOL_MODE: transaction
MAX_CLIENT_CONN: 500
DEFAULT_POOL_SIZE: 40
depends_on:
postgres:
condition: service_healthy
volumes:
pg_data:
```
```bash
docker compose up -d
psql -h 127.0.0.1 -p 6432 -U myapp mydb
```
## Maintenance Tasks
```bash
# Manual VACUUM and ANALYZE
sudo -u postgres psql -d mydb -c "VACUUM ANALYZE;"
# Reindex a bloated index
sudo -u postgres psql -d mydb -c "REINDEX INDEX CONCURRENTLY idx_orders_user_id;"
# Check for unused indexes
sudo -u postgres psql -d mydb -c "
SELECT indexrelname, idx_scan
FROM pg_stat_user_indexes
WHERE idx_scan = 0
ORDER BY pg_relation_size(indexrelid) DESC;"
```
## Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
| `FATAL: too many connections` | Connection limit reached | Increase `max_connections` or add PgBouncer |
| Slow SELECT on large table | Missing index or stale statistics | Run `EXPLAIN ANALYZE`; add index; run `ANALYZE` |
| High CPU from autovacuum | Large number of dead tuples | Tune `autovacuum_vacuum_cost_delay`; run manual `VACUUM` |
| Replication lag increasing | Replica under-provisioned or network bottleneck | Check `pg_stat_replication`; increase `wal_keep_size` |
| `could not access file "base/..."` | Disk full or corrupt data directory | Free disk space; restore from `pg_basebackup` |
| `FATAL: password authentication failed` | Wrong credentials or pg_hba.conf mismatch | Verify pg_hba.conf entries and reload |
## Related Skills
- [mysql](../mysql/) - Alternative relational database
- [database-backups](../database-backups/) - Automated backup strategies
- [redis](../redis/) - Caching layer to reduce database load
- [planetscale](../planetscale/) - Managed MySQL-compatible alternative
© devops-skills · MIT · BagelHole/DevOps-Security-Agent-Skills