Postgres
Universal .claude AI Project OS — a reusable, safe, copy-into-any-project Claude Code operating system (agents, skills, commands, presets, checklists, hooks, operating-capability docs).
npx -y skills add muxammadmamajonov/dot-claude --skill postgresAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use for PostgreSQL regardless of ORM — schema design, queries, indexing, EXPLAIN/plans, JSONB, partitions, extensions, migrations, security. Triggers — psql, SQL DDL on a Postgres stack.
SKILL.md
7.0 KB, ~1.7k tokens by cl100k_base, as published. Nobody here has run it
PostgreSQL Development
When to use
- Designing or reviewing table schemas, constraints, and indexes
- Writing or optimising complex SQL queries, CTEs, or window functions
- Authoring or debugging database migrations
- Configuring connection pooling, vacuuming, replication, or backups
- Diagnosing slow queries with
EXPLAIN (ANALYZE, BUFFERS) - Implementing row-level security, roles, or audit logging
Workflow
- Understand the access patterns first — what queries will run most frequently and at what volume? Schema design follows query design, not the reverse.
- Design the schema:
- Choose the correct data types (avoid
TEXTwhereVARCHAR(n)or a domain type is better; useTIMESTAMPTZnotTIMESTAMP; useUUIDorBIGSERIALfor PKs). - Add constraints early:
NOT NULL,UNIQUE,CHECK, foreign keys withON DELETEpolicy. - Normalise to 3NF by default; denormalise only when a proven performance need exists with a comment explaining why.
- Choose the correct data types (avoid
- Create indexes deliberately:
- Single-column B-tree for equality and range filters on high-cardinality columns.
- Composite index column order: most selective equality columns first, then range columns.
- Partial indexes for sparse conditions:
CREATE INDEX ON orders (user_id) WHERE status = 'pending'. - GIN for
jsonb, full-text search, and array containment.
- Write the migration:
- One migration file per logical change with an
upanddown(or an explicit comment if rollback is destructive). - Never add a
NOT NULLcolumn without aDEFAULTin the same statement on a live table — it rewrites the full table pre-PG11. - Add indexes
CONCURRENTLYon production tables to avoid locking.
- One migration file per logical change with an
- Write queries:
- Parameterise all user input — never string-interpolate into SQL.
- Use CTEs for readability; materialise with
MATERIALIZEDonly when the planner is misestimating. - Prefer
JOINover correlated subqueries inSELECTlist.
- Profile slow queries:
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)on the exact query with real parameters.- Look for:
Seq Scanon large tables, highRows Removed by Filter,Hash Batches > 1(spill to disk), nested loops with large outer sets. - Run
pg_stat_statementsto find top-N slow queries by total time.
- Audit for security — see .claude/checklists/security.md. Row-level security, principle of least privilege on roles, encrypted connections.
- Verify backup/restore before going live — a backup that has never been restored is an untested backup.
Standards
Schema design
- Primary keys:
BIGSERIALfor append-heavy tables;UUID(gen_random_uuid()) for distributed or externally referenced entities. - Always
TIMESTAMPTZfor timestamps — store in UTC, display in application layer. - Foreign keys must have an index on the referencing column unless they are almost never queried by FK.
- Use
ENUMtypes or a lookup table for finite, stable sets of values; useCHECK (status IN (...))for small, unlikely-to-change sets.
Migrations
- Migrations are immutable once merged — never edit a committed migration; write a new one.
- Test
upanddownmigrations in CI against a real Postgres container. - Large table changes (adding a column, changing a type): do in multiple small migrations with no-downtime patterns (expand/contract).
- Never
DROP TABLEorDROP COLUMNin the same deployment as the code that stops using it — wait one release.
Queries
- Use
RETURNINGto get generated IDs/timestamps in a single round trip instead of a follow-upSELECT. LIMIT+OFFSETpagination degrades at high offsets; use keyset pagination (WHERE id > $last_id ORDER BY id LIMIT $n).COUNT(*)is fast;COUNT(DISTINCT col)on large tables is slow — consider HyperLogLog viapg_hllfor approximations.- Wrap multi-step mutations in explicit transactions with appropriate isolation level (
READ COMMITTEDdefault;REPEATABLE READfor read-modify-write cycles).
Performance
autovacuummust be healthy: checkpg_stat_user_tables.n_dead_tup. Tuneautovacuum_vacuum_scale_factorfor large tables.- Connection pooling is mandatory at scale — use PgBouncer (transaction mode) or
pgpool-II; never open one Postgres connection per application thread. shared_buffers= 25% of RAM;effective_cache_size= 75% of RAM;work_mem= RAM / (max_connections × 2) as a starting point.
Security
- Application user has
SELECT,INSERT,UPDATE,DELETEon required tables only — neverSUPERUSERor schema-owner. - Enable
ssl = on; requirehostsslinpg_hba.conf. - Never store plain-text passwords; store argon2/bcrypt hashes.
- Use Row-Level Security (
ALTER TABLE ... ENABLE ROW LEVEL SECURITY) for multi-tenant data.
Do not
- Do not use
SELECT *in application queries — always list columns explicitly. - Do not run
VACUUM FULLorREINDEXwithout a maintenance window — they takeAccessExclusiveLock. - Do not create indexes without profiling first — every index slows writes.
- Do not use
serial/bigserialfor new projects — useGENERATED ALWAYS AS IDENTITY(SQL standard). - Do not share a database superuser account in application connection strings.
Common mistakes to avoid
| Mistake | Fix |
|---|---|
Adding a NOT NULL column to a large live table | Use ADD COLUMN col TYPE DEFAULT val, then backfill, then add NOT NULL in a later migration (PG<11). PG11+ handles this in one DDL. |
| Index not used despite existing | Check column order, data type mismatch, or function wrapping in WHERE clause (WHERE lower(email) = ? needs functional index). |
LIKE '%term%' not using index | Use pg_trgm GIN index: CREATE INDEX ON t USING gin (col gin_trgm_ops). |
| Long-running transaction blocking autovacuum | Set statement_timeout and idle_in_transaction_session_timeout in postgresql.conf. |
| JSONB overuse replacing relational columns | Use JSONB for truly variable/schemaless attributes; model known fields as typed columns. |
Missing FOR UPDATE in optimistic lock patterns | Use SELECT ... FOR UPDATE or UPDATE ... WHERE version = $v with row count check. |
Output format
- Schema change:
CREATE TABLEorALTER TABLEDDL with all constraints, followed byCREATE INDEXstatements. - Migration file: numbered file (
YYYYMMDDHHMMSS_description.sql) with-- migrate:upand-- migrate:downsections. - Query optimisation: original query,
EXPLAIN ANALYZEsnippet of the problem node, rewritten query, and expected improvement. - Role/permission setup:
CREATE ROLE,GRANT,REVOKEstatements with comments on why each privilege is granted.
Related checklists
- .claude/checklists/security.md
- .claude/checklists/performance.md
- .claude/checklists/qa.md
Related agents
- .claude/agents/core/orchestrator.md
- .claude/agents/engineering/database-architect.md
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.