CapyDB Docs
Guides

Cutovers

Operator-assisted promotion of a preview database to production, with a verified pre-cutover backup taken first.

What a cutover is

A cutover takes a preview database you have already built and verified — a rehearsed schema migration, a cleaned-up import, a restructured dataset — and makes its contents the project's production data. It is the "this preview is the new production" operation.

It is deliberately not self-service. You open a cutover request; a platform operator reviews it, schedules it with you, and executes it. Overwriting production from a human-prepared database is the kind of action that benefits from a second pair of eyes, and we would rather be slow here than sorry.

Cutover vs. restore

Both end with production overwritten, so pick by where the desired state lives:

You want production to become...Use
A past state of production (backup, restore point, or timestamp)Restore with target_kind: "project" — self-service, gated by a confirmation flag and the org admin role
The current state of a preview database you preparedCutover — operator-assisted

If you only want to inspect a candidate state, neither: restore into a preview and look around first.

The flow

  1. Request. From the project's Previews tab (the Promote action on a ready preview) or POST /v1/projects/{id}/cutover-requests with the preview_id. You can attach a customer_note (up to 1000 characters) and an external_ticket_ref (up to 120 characters) — a reference to the support thread or ticket where the cutover is coordinated. A ticket reference is required before the cutover can be executed, so include it up front or expect the operator to ask for it.
  2. Review. The request opens in open state. An operator acknowledges it (acked) or rejects it with a stated reason (rejected). One open request per preview at a time.
  3. Execution. The operator triggers the promotion. Before anything is overwritten, a backup of the current production database is taken and verified, labeled pre-cutover-<request-id> — it appears in your backups list like any other and is your rollback path. The preview's contents are then copied over the production database. The request moves through in_progress to completed.

The preview must be ready and not expired for the whole flow — watch the TTL, and extend it if review takes longer than the preview lives.

What changes and what does not

  • Connection strings do not change. The project keeps its host, ports, database name, role, and password. Apps reconnect to the same URLs and see the new data.
  • The source preview database is not consumed — its contents are copied, and the preview remains until its TTL removes it.
  • The project passes through a restoring state while the job runs; it does not accept other lifecycle operations during that window.

After completion

  • restore.completed and job.completed webhook events fire.
  • Connected Vercel and Netlify integrations re-push env vars (unchanged here, but the sync runs for consistency).
  • The audit trail records the full lifecycle: cutover.requested, cutover.acked (or cutover.rejected), cutover.promote_started, and a production_overwrite_restore event carrying the pre-cutover backup ID.

Rolling back

The pre-cutover backup is a normal backup. If the cutover turns out to be a mistake, restore from it — into a preview first to confirm, then over production.

Limitations, stated plainly

  • Cutovers run when an operator runs them. There is no SLA on turnaround; the external_ticket_ref exists precisely so timing is agreed between humans.
  • The promotion job does not retry on failure — a failed cutover stays failed and an operator investigates rather than the system blindly re-overwriting production.
  • There is no CLI command for cutovers today; use the dashboard or the API.