agentsclimarketplace

Writing safe migrations

Skill pumarogie/claude-postgres-skills/skills/writing-safe-migrations

Production Postgres survival skills for Claude Code — schema design, safe migrations, query performance, connection pooling, autovacuum/bloat, and queue/partitioning patterns.

Install
npx -y skills add pumarogie/claude-postgres-skills --skill writing-safe-migrations

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 15 days oldThe repository was created 15 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
  • 1 stars1 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 when altering tables, adding indexes or constraints, or writing any Postgres migration that runs against a large or live table.

SKILL.md

2.7 KB, 586 tokens by cl100k_base, as published. Nobody here has run it

Writing Safe Migrations

Overview

Before running any migration, answer one question: does this block all my writes, or not? Many DDL statements take a lock that stalls every insert/update on the table until they finish — fatal on a large live table. The safe variants exist to avoid exactly that.

When to Use

  • Adding an index to an existing large table.
  • ALTER TABLE, adding columns, or adding check constraints.
  • Any migration on a table with meaningful traffic.
  • Writing update-heavy queries inside transactions.

Quick Reference

OperationDangerSafe way
CREATE INDEXLocks table against writesCREATE INDEX CONCURRENTLY
Add check/FK constraintFull-table scan blocks writesAdd NOT VALID, then VALIDATE CONSTRAINT later
Dropping columnsHard to roll backKeep migrations additive; expand-and-contract
Long transactionHolds locks, blocks autovacuumKeep transactions short

Patterns

-- Build the index without locking writes (cannot run inside a transaction block)
CREATE INDEX CONCURRENTLY idx_tasks_tenant ON tasks (tenant_id);

-- Add a constraint without a write-blocking full-table scan, validate afterwards
ALTER TABLE tasks ADD CONSTRAINT chk_status
    CHECK (status IN ('pending','running','done')) NOT VALID;
ALTER TABLE tasks VALIDATE CONSTRAINT chk_status;  -- takes only a lighter lock

Rules

  • Additive migrations. Prefer adding over removing. Avoid dropping/renaming columns in the same deploy that changes app code. For unavoidable changes use expand-and-contract: add new → backfill → switch reads/writes → remove old, across separate deploys.
  • Wrap in a transaction where possible so a failure rolls back cleanly. Note CREATE INDEX CONCURRENTLY cannot run inside a transaction block.
  • Short transactions. Every UPDATE holds a row-level lock until commit, and long transactions block autovacuum (see tuning-autovacuum-and-bloat). Lock only the rows you actually need.
  • No external calls mid-transaction. Don't hold a transaction open across an HTTP/RPC call — the locks stay held for the whole round trip.

Common Mistakes

  • CREATE INDEX (without CONCURRENTLY) on a big live table — blocks all writes for the whole build.
  • Adding a check/FK constraint without NOT VALID — the validation scan blocks writes.
  • A transaction that makes an external API call while holding row locks — turns a fast update into a lock held for seconds.
  • Destructive column drops coupled to the same release as the code change — no clean rollback path.

What ships with it: 1 file

5.7 KB alongside SKILL.md

reference/

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.