Skip to content

CONCEPT Cited by 3 sources

Staged-then-sealed migration

Definition

A staged-then-sealed migration is an online schema change that deliberately holds its cut-over indefinitely: the migration backfills the shadow table, catches up to the current binlog position, and then continues tailing the binlog forever — waiting for an external signal to seal (cut over). The catch-up phase becomes a stable, long-lived state rather than a brief transition before the swap.

This is the mechanical shift that makes gated deployment work: a long-running migration can park in catch-up mode while other migrations in the same deploy-unit complete their own copy + catch-up phases. When every migration in the unit reports ready-to-seal, the deploy controller opens the gate and seals them all together.

Canonical verbatim framing:

"This emulation mechanism is what allows us some concurrency and control over the cut-over timing. As we complete copying over a table's existing data set, we can continue to watch the ongoing changes to the table, technically indefinitely, or until we decide that it's time to cut over."

(Source: sources/2026-04-21-planetscale-deploying-multiple-schema-changes-at-once)

Mechanism

Under normal shadow-table online DDL flow:

  1. Build shadow — create target-schema table.
  2. Backfill — copy existing rows under consistent snapshot, recording GTID positions.
  3. Catch up — apply binlog events post-snapshot via binlog replication through the DDL's column projection.
  4. Cut over — brief write-lock, drain residual events, RENAME TABLE.

The staged-then-sealed variant inserts an indefinite wait between steps 3 and 4:

  1. Catch up — reach parity with live binlog. 3.5. Stay in catch-up — continue tailing the binlog event-for-event, applying to the shadow through the DDL projection, for hours to days if necessary. Ready flag is published to the deploy controller.
  2. Cut over — triggered by the deploy controller when every migration in the gate reports ready.

The shadow table is "perpetually-almost-ready" — never more than a few seconds of binlog behind the live table, but never swapped.

Resource cost

Holding migrations in staged-then-sealed state is not free:

  • Storage amplification — every staged migration holds a full shadow table; N migrations on TB-scale tables require N × TB of transient storage.
  • Binlog retention becomes load-bearing — the binlog must be retained for as long as the longest-running migration is staging. If retention expires, the migration cannot catch up from scratch without re-starting the backfill.
  • Replication cost — each migration is tailing the binlog continuously; CPU + I/O scales with number of concurrent stages.
  • schemadiff must accept the branch — the library rejects deploy- request branches whose complexity exceeds a "reliably safe path" threshold, capping practical concurrent staging count.

The post's disclaimer: "Resources are not infinite, and only so many changes can run concurrently. Altering a hundred tables in one deployment request is not feasible."

Why the catch-up phase is a stable state

The shadow- table pattern already tails the binlog during catch-up — extending this indefinitely is a trivial operational extension. The shadow stays within a few seconds of live; the mechanism that ensures this (binlog-following) is the same mechanism that handles actual cut-over drain. The difference is purely a question of when the cut-over signal fires.

Composition with gated deployment

Staged-then-sealed is the per-migration mechanism; gated deployment is the orchestration layer above it that coordinates multiple staged migrations into a single cut-over event.

A single staged migration is indistinguishable from a regular online DDL with a human-delayed cut-over. The property only becomes valuable when N migrations stage in parallel and the deploy controller seals them all when the last one catches up.

Seen in

  • sources/2026-04-21-planetscale-gated-deployments-addressing-the-complexity-of-schema-deployments-at-scale — earliest canonical wiki disclosure of the "indefinite catch-up" property. Shlomi Noach's 2022 Gated Deployments launch post: "With no input from the user, the deployment will just keep on running in the background, always keeping up to date with data changes." The 2022 post canonicalises the operator-scheduled variant where the seal signal is a user click rather than a system-driven ready-to-complete event — see patterns/operator-scheduled-cutover. The scheduling rule "we run as much of the bulk work as possible upfront, sequentially, and then run the more lightweight work in parallel" is also named here for the first time on the wiki.
  • sources/2026-04-21-planetscale-deploying-multiple-schema-changes-at-once — canonical wiki disclosure. Shlomi Noach introduces the "indefinite catch-up" framing as the enabling primitive for near-atomic multi-change deployment. The mechanism is not separately named in the post; this page canonicalises it as "staged-then-sealed." Related framing from the post: "We may alternate between the copying phases — the heavy-lifting part of the emulation — of the different tables and only parallelize the tailing of the ongoing changes" — the concurrency model for multiple staged migrations.
  • sources/2026-04-21-planetscale-behind-the-scenes-how-schema-reverts-work — sibling disclosure. Guevara + Noach describe how VReplication keeps the stream alive post-cut-over to power instant schema revert. Staged-then-sealed is the symmetric shape pre-cut-over: kept-alive-before for gated deployment, kept-alive-after for instant revert. The two together make a VReplication stream a continuous, operator-controlled pipe rather than a one-shot migration.
Last updated · 347 distilled / 1,201 read