api-pagination
Implement correct, fast API pagination — cursor vs offset trade-offs, opaque cursor encoding, stable sort keys, page-size limits, total-count costs, and…
How to write safe, reversible, zero-downtime database schema migrations — additive-first changes, the expand/migrate/contract pattern, batched backfills, concurrent index builds, safe NOT NULL, rollbacks, and the locking pitfalls that cause outages. A deep reference with
$ npx -y skills add vanara-agents/skills --skill database-migrations --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/database-migrationsContext preview
The summary Claude sees to decide when to auto-load this skill.
How to write safe, reversible, zero-downtime database schema migrations — additive-first changes, the expand/migrate/contract pattern, batched backfills, concurrent index builds, safe NOT NULL, rollbacks, and the locking pitfalls that cause outages. A deep reference with
name: database-migrations description: How to write safe, reversible, zero-downtime database schema migrations — additive-first changes, the expand/migrate/contract pattern, batched backfills, concurrent index builds, safe NOT NULL, rollbacks, and the locking pitfalls that cause outages. A deep reference with runnable checks. type: skill version: 2.0.0 updated: 2026-06-29
A migration runs against **live data while old code may still be serving traffic**. The dangerous moment is never the steady state before or after — it's the in-between, when the schema has changed but not every app instance has. Design every change to be correct *during* that window. Heavy detail lives in `references/`; copy-paste material in `examples/`; a runnable safety check in `scripts/`.
Two things deploy on different clocks: your **schema** (one atomic change) and your **code** (rolled out instance-by-instance over minutes). A migration is safe only if **both the old and new code work against both the old and new schema** for the overlap window. That single rule explains almost every practice below.
| Concern | Safe answer | |---|---| | What changed | the smallest possible step | | When old code sees it | it must still work (backward-compatible) | | Locks held | none long enough to block traffic | | If it goes wrong | a tested, reversible path back | | Big rename/retype | expand → migrate → contract, across deploys |
Prefer **additive, backward-compatible** changes. Adding a nullable column, adding a table, or adding an index never breaks code that doesn't know about it. Destructive changes (drop/rename column, change type, add `NOT NULL`) break the old code still running mid-deploy, so they must be sequenced — see §3.
-- SAFE: old code ignores the new column; new code can start using it. ALTER TABLE users ADD COLUMN email_verified_at timestamptz NULL; -- UNSAFE in one step: old code still INSERTs rows without this column. ALTER TABLE users ADD COLUMN email_verified_at timestamptz NOT NULL;
Most outages from migrations are **lock waits**, not data loss. A statement that rewrites a table or takes an `ACCESS EXCLUSIVE` lock blocks every read/write behind it, and that queue backs up into your connection pool within seconds.
metadata-only and does not rewrite the table; a *volatile* default does).
inside a transaction).
SET lock_timeout = '3s'; -- fail fast rather than queue behind traffic CREATE INDEX CONCURRENTLY idx_orders_status ON orders (status);
Full catalogue of which operations rewrite/lock and the safe alternative: `references/zero-downtime-changes.md`.
The core pattern for any breaking change (rename, retype, split, add `NOT NULL`) without downtime. It spreads one logical change across **multiple deploys** so old and new code always overlap safely:
1. **Expand** — add the new shape (nullable column / new table / new index). Backward-compatible. 2. **Migrate** — deploy code that **dual-writes** old+new, then **backfill** existing rows in batches, then switch **reads** to the new shape and verify. 3. **Contract** — once nothing reads or writes the old shape, drop it in a *later* deploy.
Each step is independently deployable and independently reversible. The full worked walkthrough (including a column rename and a non-null-ification) is in `references/expand-contract.md`.
Every migration should declare how to undo it. Some operations are **irreversible** in practice (`DROP COLUMN`, `DROP TABLE`, `TRUNCATE` destroy data; a down-migration can recreate the *structure* but not the *data*). Treat those specially:
backup**, and take a verified backup/snapshot immediately before.
Reversible-vs-irreversible rules, backup checklists, and dry-run guidance: `references/rollback-and-safety.md`. Validate a `.sql` file with `scripts/check-migration-reversible.mjs` before shipping.
ambiguous and the transaction huge.
already ran against live data; keep `down` for local/staging and emergencies.
doesn't error.
bloat WAL/replication lag.
full validating scan. Add nullable, backfill, then `SET NOT NULL` (validate via a `CHECK ... NOT VALID` then `VALIDATE`). See the zero-downtime reference.
Use exp
🐒 Free agents, skills & packs for Claude Code One subscription. An army of Claude Code agents. 30 production-grade agents, skills, and packs for Claude Code — free, Apache-2.0, install with one command.
Repo: vanara-agents/skills
Implement correct, fast API pagination — cursor vs offset trade-offs, opaque cursor encoding, stable sort keys, page-size limits, total-count costs, and…
Deep reference for caching — what to cache, cache-aside vs read/write-through/write-behind, TTLs with jitter, eviction (LRU/LFU/FIFO), invalidation, and…
Write Conventional Commits — the type(scope)!: subject + body + footer spec — so history is readable and changelogs and SemVer bumps can be derived…
How to handle errors explicitly and consistently across an app — validate at boundaries, classify operational vs programmer errors, add context while…
Run git collaboration that scales — trunk-based vs git-flow decided by deploy cadence, branch protection and required checks, PR sizing and review etiquette,…
A deep prevention reference for the OWASP Top 10 web risks — broken access control, injection, crypto failures, insecure design, SSRF and more — with…