PluginBench
Skill
Pass
Audit score 90

convex-migrate-rehearse

get-convex/agent-skills

Rehearse schema changes on a preview deployment before promoting to production with snapshot rollback.

What is convex-migrate-rehearse?

This skill safely tests Convex schema migrations by seeding a preview deployment with production data, running the schema change and backfill there, verifying it succeeds, then promoting the proven change to prod. Use it whenever you need to modify a live app's schema with confidence that the data-conformance gate will pass.

  • Snapshot production data and seed a preview deployment with it before any schema edits
  • Push optional schema changes to the preview, catching conformance failures on a copy not prod
  • Run batched, resumable backfills via @convex-dev/migrations to migrate existing rows
  • Verify the migrated data and tightened schema on the preview before touching production
  • Promote the same proven sequence to prod with the snapshot retained as a rollback artifact
  • Classify source and target deployments and require explicit confirmation before prod changes

How to install convex-migrate-rehearse

npx skills add https://github.com/get-convex/agent-skills --skill convex-migrate-rehearse
Prerequisites
  • A Convex project with a preview deployment capability (paid tier)
  • A Preview Deploy Key exported as CONVEX_DEPLOY_KEY in your environment
  • The @convex-dev/migrations package for running batched backfills
  • Access to both source (prod) and target (prod) deployments for the promote step
Claude Code
Cursor
Windsurf
Cline

How to use convex-migrate-rehearse

  1. 1.Run deploy-guard to classify source and target deployments and get explicit confirmation for the prod promote
  2. 2.Export a snapshot from the production deployment: npx convex export --path snapshot.zip (add --include-file-storage if the migration touches files)
  3. 3.Create a preview deployment from the pre-change code: npx convex deploy --preview-create migrate-<slug>
  4. 4.Seed the preview with the snapshot: npx convex import snapshot.zip --deployment migrate-<slug>
  5. 5.On the preview, push the optional schema change: npx convex deploy --preview-name migrate-<slug>
  6. 6.Write and run a @convex-dev/migrations backfill against the preview to migrate all existing rows
  7. 7.Verify the migrated data by running app functions against the preview deployment
  8. 8.Tighten the validator (make the field required or narrow the union) and push again to the preview

Use cases

Good for
  • Adding a required field to an existing table by first making it optional, backfilling, then tightening
  • Narrowing a union type or validator on a field that already has data
  • Changing the shape of documents in a live app without losing or corrupting data
  • Testing a complex multi-step migration on prod-shaped data before applying it to the real database
  • Rolling back a schema change by restoring the pre-migration snapshot if needed
Who it's for
  • Backend engineers managing Convex databases with live production data
  • Teams that need to validate schema changes against real data before committing them
  • Developers building data migrations that must not fail on production

convex-migrate-rehearse FAQ

Why create the preview before editing schema.ts?

The preview must be seeded with the snapshot before any schema changes. If you edit schema.ts first, the import will fail because the snapshot data no longer conforms to the new schema. Create the preview on the old code, import the snapshot, then edit and push the new schema to the preview.

What if the preview push fails on the conformance gate?

That is the intended behavior — the gate catches data that violates the new schema. Fix the offending rows via the backfill logic, re-run the backfill on the preview, and push again. Once the preview is green, the prod push will succeed because it repeats a proven run on prod-shaped data.

Can I use convex dev instead of a preview deployment?

If a preview deployment is not available (no preview key or not on a paid tier), you can seed your personal dev deployment with the snapshot and rehearse there instead. The workflow is the same; just use convex dev and note that you are rehearsing on dev, not a true preview.

What happens to data written after the snapshot is imported?

A snapshot restore loses all data written after the snapshot was taken. Keep the promote window short and communicate the downtime window clearly. The snapshot is retained as a rollback artifact only; do not use it as a backup for ongoing data.

Should I commit the snapshot.zip file to version control?

No. The snapshot contains real production data and should be treated as sensitive. Delete it locally once the promote is complete and verified. Never commit it to your repository.

Full instructions (SKILL.md)

Source of truth, from get-convex/agent-skills.


name: convex-migrate-rehearse description: "Rehearse a live-app schema change + backfill on a snapshot-seeded preview deployment, verify, then promote the proven change to prod with the snapshot as rollback."

<!-- GENERATED from convex-agents content/capabilities/migrate-rehearse.json — do not edit by hand. -->

Rehearse a schema change on a preview before prod

A schema push on Convex validates every existing document against the new schema and FAILS the push if any row doesn't conform — a real data-conformance gate. The safe way to use that gate is to let it fail on a rehearsal copy, not on prod. This capability turns a preview deployment into that copy: seed it with a prod snapshot, push the new schema + run the backfill there, watch the gate, and only promote once it's green. It composes deploy-guard (target classification), migrate (the optional-then-tighten pattern), and @convex-dev/migrations (the batched, resumable backfill).

Workflow

  1. PRECONDITION: preview deployments need a Preview Deploy Key (dashboard → Project Settings → Deploy Keys → Preview) exported as CONVEX_DEPLOY_KEY before any --preview-create/--preview-name deploy — a plain npx convex login session cannot create previews, and this is a paid-tier feature. If no preview key is available, fall back to rehearsing on the personal dev deployment seeded with the snapshot, and say so.
  2. GUARD: deploy-guard — classify + announce the SOURCE (prod, being read) and the eventual TARGET (prod, being changed); get the fresh explicit yes for the prod promote up front and confirm the plan.
  3. SNAPSHOT the source data read-only: npx convex export --path snapshot.zip (from the deployment holding the real data; add --include-file-storage only if the migration touches files). This is a read; it changes nothing.
  4. CREATE the preview FROM THE PRE-CHANGE CODE — do this BEFORE editing schema.ts, so the preview starts on the schema the snapshot data already conforms to: npx convex deploy --preview-create migrate-<slug> (needs the preview key; auto-expires ~5 days). Seed it: npx convex import snapshot.zip --deployment migrate-<slug> (import targets a deployment by NAME with --deployment; there is no --preview-name flag on import). The import succeeds because the data still matches the old schema.
  5. REHEARSE on the preview, in the migrate order — each push is npx convex deploy --preview-name migrate-<slug> (re-deploys to the SAME preview, keeping its data; NOT convex dev, which targets personal dev): (a) make the new/changed field OPTIONAL and deploy — if existing rows violate it the push FAILS HERE on the copy with the offending shape; fix and re-push until green. (b) write a @convex-dev/migrations backfill and run it against the preview; verify every row is now valid. (c) tighten the validator (required / narrowed union) and deploy again — the gate now passes because the backfill ran.
  6. VERIFY on the preview: run the app's functions against the migrated data (MCP run/runOneoffQuery pointed at the preview, or a smoke query) to confirm behavior and shape.
  7. PROMOTE only on the fresh explicit yes from step 1: apply the SAME sequence to prod (optional schema → backfill → tighten). Because it already succeeded on prod-shaped data, the prod push repeats a proven run. Keep the snapshot as the rollback artifact (npx convex import snapshot.zip --replace --prod); state plainly that data written after the snapshot is lost, so keep the promote window short.
  8. CLEAN UP: the preview auto-expires; delete the local snapshot when done (it holds real data — treat it as sensitive, never commit it).

Rules

  • Create the preview from the PRE-CHANGE code and seed the snapshot BEFORE editing schema.ts — so the import conforms and the conformance gate then fails on the copy (not prod) when you push the change; each preview push is deploy --preview-name, import targets it with --deployment.
  • Follow the migrate order every time: optional field → push → backfill → verify → tighten → push; skipping 'optional first' makes the very first push reject existing rows.
  • The prod promote needs a fresh explicit yes (deploy-guard) and is a REPEAT of the proven preview run, not a new attempt.
  • Keep the prod snapshot as the rollback artifact; state plainly that a snapshot-restore loses data written after the snapshot, so keep the promote window short.
  • Treat the exported snapshot as sensitive real data: delete it locally when finished; never commit it.
  • Backfills go through @convex-dev/migrations (batched, resumable, dry-runnable), not ad-hoc one-shot mutations over a whole table.
  • This is the rehearsal-and-promote flow; for the plain 'explain optional-then-tighten' guidance with no live data, that's migrate.