# Migration

> Move or copy a database to another instance or server with a backup, restore, and verify saga — prerequisites, downtime, and failure recovery.

Source: https://fleetdock.dev/docs/migrations


A **migration** relocates or copies a database to another instance, potentially on another
server. Fleetdock runs it as a background **saga**: backup → restore → verify → optionally
drop the source.

## Copy vs move [#copy-vs-move]

Start a migration from a database's detail page (**Move**) and watch it on the **Moves**
page.

* Leave **drop source** unticked to make a **copy** — the original stays in place.
* Tick **drop source** to make a true **move** — the source is dropped after a successful,
  verified restore (a cutover).

## How the saga works [#how-the-saga-works]

<Steps>
  <Step>
    ### Backup [#backup]

    Fleetdock takes a backup of the source database.
  </Step>

  <Step>
    ### Restore [#restore]

    It restores that backup into the destination instance and database name.
  </Step>

  <Step>
    ### Verify [#verify]

    It verifies the backup's SHA-256 checksum before writing, then counts restored tables.
  </Step>

  <Step>
    ### Optional drop [#optional-drop]

    If you chose to move (not copy), the source database is dropped after verification.
  </Step>
</Steps>

## Prerequisites [#prerequisites]

* The **destination instance** exists and is reachable from the executing side.
* The destination node has enough **disk capacity** for the copied data.
* Valid credentials for both source and destination.

## Destination capacity [#destination-capacity]

Confirm the destination node has headroom before starting — Fleetdock reports node CPU,
memory, and disk but does not currently block a migration on insufficient capacity.

## Credential handling and endpoints [#credential-handling-and-endpoints]

Every database has a **private** endpoint on its instance (`server.address:published-port`).
If **public access** is enabled, it also has a **gateway** endpoint
(`FLEETDOCK_GATEWAY_PUBLIC_HOST:assigned-port`) that stays stable across migrations — only
the private backend target changes when you move a database to another server.

**Applications are not repointed automatically.** After a move:

* **Public access enabled** — update credentials if you rotated them; hostname and gateway
  port stay the same.
* **Private access only** — update your application's host and port to the destination
  instance's private endpoint.

See [External database access](/docs/external-access) for gateway setup and application
credentials.

## Downtime [#downtime]

<Callout type="warn">
  Migrations are **not zero-downtime**. The copy is taken from a backup at a point in time,
  so writes to the source after the backup are not carried over. For a clean cutover, stop
  writes to the source (or accept the backup as the consistency point) before dropping it and
  switching applications to the destination.
</Callout>

## Validation [#validation]

The verify step (checksum + restored table count) gives you a concrete success signal before
any source data is dropped. Review the operation on the **Moves** / **Operations** page.

## Cleanup [#cleanup]

For a **copy**, remove the source manually if and when you no longer need it. For a **move**,
the source database is dropped as part of the saga; the source instance and node remain.

## Failure recovery [#failure-recovery]

<Callout type="info">
  If a migration fails before the drop step, the source database is left untouched — retry
  after fixing the cause (capacity, connectivity, or credentials). Because the source is only
  dropped **after** a verified restore, a failed copy or restore does not destroy your source
  data.
</Callout>

Detailed, step-by-step migration failure recovery is still being expanded in the product
documentation; see [Restore failure scenarios](/docs/restores#failure-scenarios) for the
restore phase, which is the same machinery the migration uses.
