docs/content/stable/yugabyte-voyager/reference/iterative-cutover.md
Iterative cutover extends live migration with fall-back by allowing multiple rounds of cutover between a PostgreSQL source and YugabyteDB target. Instead of treating a fall-back (cutover to source) as a terminal event, you can restart source-to-target data migration, creating a new CDC-only streaming iteration without re-importing the initial snapshot.
This is useful in the following cases:
Iterative cutover only works with live migration with fall-back (that is, cutover to target was run with --prepare-for-fall-back true) running on a PostgreSQL source.
Iterative cutover is not supported for fall forward or Oracle/MySQL sources.
To perform iterative cutovers, do the following:
Start live migration with fall-back, and follow the standard live migration with fall-back steps.
Cut over to target using prepare-for-fall-back as usual.
When performing a cutover to source, add the restart flag.
{{< tabpane text=true >}}
{{% tab header="Config file" lang="config" %}}
Add the following to your configuration file:
...
initiate-cutover-to-source:
restart-data-migration-source-target: true
...
Then run the following command:
# Replace the argument values with those applicable for your migration.
yb-voyager initiate cutover to source --config-file <path-to-config-file>
{{% /tab %}}
{{% tab header="CLI" lang="cli" %}}
# Replace the argument values with those applicable for your migration.
yb-voyager initiate cutover to source --export-dir <EXPORT_DIR> --restart-data-migration-source-target true
{{% /tab %}}
{{< /tabpane >}}
This tells Voyager to start a new forward iteration after the fall-back completes. If you omit this flag or set it to false, the fall-back is terminal and no new iteration is created.
Monitor the new iteration. After fall-back completes, Voyager automatically starts the next iteration.
Cut over to target again. When the new iteration has caught up, initiate cutover to target with --prepare-for-fall-back true.
Repeat steps 2-5 as many times as needed.
Final cutover. When satisfied, cut over to target without --prepare-for-fall-back, or cut over to target with --prepare-for-fall-back and then run end migration.
When iterations exist, the cutover status includes rows for each iteration.
By default, the data migration report aggregates event counts (inserts, updates, deletes) across all iterations into a single view per table.
For detailed per-iteration data migration reporting, add the --include-detailed-iterations-stats flag. This adds an ITERATION NUMBER column showing per-iteration statistics and a CUMULATIVE FINAL_ROW_COUNT (row count up to that iteration). Iteration 0 includes snapshot rows; subsequent iterations show only change events.
The archive changes command supports iterative migrations. When iterations are present, the command processes the parent export directory and, at the end, provides the directory location for archiving the next iteration. Use the --archive-dir flag to specify the directory location.
The end migration command handles iterative migrations by ending each iteration in sequence (1 through N), then ending the parent migration (iteration 0). Specifically, the command does the following:
Iterates through each iteration (1 through N), ending each one and cleaning up its migration state.
Ends the parent migration (iteration 0), cleaning up source and target database state.
If --save-migration-reports is enabled, saves all reports. This includes a consolidated data migration report with detailed iteration statistics.
The consolidated report is saved to {BACKUP-DIR}/reports/data-migration-report.json. Backup data for each iteration is saved in a subdirectory of the backup directory ({BACKUP-DIR}/live-data-migration-iterations/live-data-migration-iteration-N/), with data, schema, and logs subfolders.