> For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt

# Finalize Cutover Process

You can finalize a migration and transfer your application workload from the source to the destination cluster using the [mongosync](https://www.mongodb.com/docs/mongosync/current/reference/mongosync-binary.md#std-label-c2c-mongosync) cutover process.

`mongosync` should remain active until it reaches the [COMMITTED](https://www.mongodb.com/docs/mongosync/current/reference/mongosync-states.md#std-label-c2c-state-committed) state. This allows `mongosync` to sync any additional writes that occur during the migration.

**Note:**

Before you switch your application workload to the destination cluster, you should always verify a successful sync. For more information, see [Verify Data Transfer.](https://www.mongodb.com/docs/mongosync/current/reference/verification.md#std-label-c2c-verification)

## Steps

1. Verify the status of mongosync.

   Call the [progress](https://www.mongodb.com/docs/mongosync/current/reference/api/progress.md#std-label-c2c-api-progress) endpoint to determine the status of `mongosync` before starting the cutover process. Ensure that the `mongosync` process status indicates the following values:

   - `canCommit` is `true`.

   - `lag.overallLagSeconds` is small (near `0`).

     If `lag.overallLagSeconds` isn't close to `0` when the cutover starts, cutover might take a long time.

   - When using the [Embedded Verifier](https://www.mongodb.com/docs/mongosync/current/reference/api/start.md#std-label-c2c-start-verifier) check **both** the `verification.source` and the `verification.destination` return documents. The `lagTimeSeconds` fields in both documents should be near `0` and the `phase` fields should show `"stream
     hashing"`.

     If the verifier is not in the stream hashing phase, the cutover process might take a long time.

   The following example returns the status of the synchronization process.

   ##### Request

   ```shell
   curl localhost:27182/api/v1/progress -XGET

   ```

   ##### Response

   ```json
   {
      "progress":
         {
            "state":"RUNNING",
            "canCommit":true,
            "canWrite":false,
            "info":"change event application",
            "ceaStage":"steady state",
            "lag": {
               "overallLagSeconds": 0,
               "crudLagSeconds": 0,
               "ddlLagSeconds": null
            },
            "lagTimeSeconds":0,
            "collectionCopy":
               {
                  "estimatedTotalBytes":694,
                  "estimatedCopiedBytes":694
               },
            "directionMapping":
               {
                  "Source":"cluster0: localhost:27017",
                  "Destination":"cluster1: localhost:27018"
               },
            "source":
               {
                  "pingLatencyMs":250
               },
            "destination":
               {
                  "pingLatencyMs":-1
               },
            "verification":
               {
                  "source":
                     {
                        "estimatedDocumentCount": 42,
                        "hashedDocumentCount": 42,
                        "lagTimeSeconds": 2,
                        "totalCollectionCount": 42,
                        "scannedCollectionCount": 10,
                        "phase": "stream hashing"

                     },
                  "destination": {
                        "estimatedDocumentCount": 42,
                        "hashedDocumentCount": 42,
                        "lagTimeSeconds": 2,
                        "totalCollectionCount": 42,
                        "scannedCollectionCount": 10,
                        "phase": "stream hashing"
                  }
               }
         },
      "success": true
   }

   ```

2. Stop any write operations to the synced collections on the source.

   - Wait for all transactions on the source cluster to either commit or abort.

   - `mongosync` manages write blocking based on your migration configuration. To learn more, see [Write Blocking.](https://www.mongodb.com/docs/mongosync/current/reference/mongosync-behavior.md#std-label-c2c-write-blocking)

   - If `mongosync` uses filtered sync, it's not necessary to disable writes to the entire source cluster. However, you must ensure that you stop write operations for the collections that the filter includes.

3. Send a [commit](https://www.mongodb.com/docs/mongosync/current/reference/api/commit.md#std-label-c2c-api-commit) request to `mongosync`.

   If you start multiple `mongosync` instances for your migration, you must issue a commit request for each `mongosync` instance.

   ##### Request

   ```shell
   curl localhost:27182/api/v1/commit -XPOST --data '{ }'

   ```

   ##### Response

   ```json
   {"success":true}

   ```

   **Note:**

   After you submit a `commit` request, call the `progress` endpoint to ensure that the `mongosync` state is `COMMITTING` or `COMMITTED`.

   If your source cluster contains Persistant Query Settings (PQS), you must [manually migrate PQS](https://www.mongodb.com/docs/mongosync/current/reference/c2c-migrate-pqs.md#std-label-c2c-migrate-pqs) to your destination cluster.

   In the [default configuration](https://www.mongodb.com/docs/mongosync/current/reference/mongosync-behavior.md#std-label-c2c-write-blocking), `mongosync` blocks writes on the source cluster once you complete this step.

   If `mongosync` crashes during this step, you may need to manually unblock writes on the source cluster by running the following command:

   ```javascript
   db.adminCommand(
     {
       setUserWriteBlockMode: 1,
       global: false
     }
   )
   ```

4. Wait until you can perform writes on the destination cluster.

   Call the `progress` endpoint to determine if `canWrite` is `true`. If `canWrite` is `false`, wait until `progress` shows `canWrite` is `true`. If you are running [multiple mongosync instances](https://www.mongodb.com/docs/mongosync/current/topologies/multiple-mongosyncs.md#std-label-c2c-sharded-config), only check that `canWrite` is true on the first `mongosync` process. The `canWrite` status of any subsequent `mongosync` processes is not valid.

   ```bash
   curl -sS localhost:27182/api/v1/progress -XGET | jq ".progress.canWrite"
   ```

   **Output:**

   ```json
   true
   ```

5. Verify data transfer.

   Verify the successful sync of data from the source to the destination cluster.

   For more information, see [Verify Data Transfer.](https://www.mongodb.com/docs/mongosync/current/reference/verification.md#std-label-c2c-verification)

6. If you manually blocked writes on the destination cluster by using [`setUserWriteBlockMode`](https://www.mongodb.com/docs/manual/reference/command/setUserWriteBlockMode.md#mongodb-dbcommand-dbcmd.setUserWriteBlockMode), enable application writes on the destination cluster.

   To enable writes, update [`setUserWriteBlockMode`:](https://www.mongodb.com/docs/manual/reference/command/setUserWriteBlockMode.md#mongodb-dbcommand-dbcmd.setUserWriteBlockMode)

   ```javascript
   db.adminCommand(
      {
         setUserWriteBlockMode: 1,
         global: false
      }
   )

   ```

   Then, transfer your application workload to the destination cluster.

7. Call the `progress` endpoint to determine the status of the `mongosync` process.

   When the `mongosync` progress response indicates that the `mongosync` state is `COMMITTED`, the cutover process is complete.

   ```bash
   curl -sS localhost:27182/api/v1/progress -XGET | jq ".progress.state"
   ```

   **Output:**

   ```json
   "COMMITTED"
   ```

8. Drop the metadata databases on the destination cluster.

   `mongosync` stores its metadata in a database or multiple databases during migration. The metadata databases can be named any of the following:

   - `__mdb_internal_mongosync`

   - Anything beginning with `__mdb_internal_mongosync_verifier`

   Drop any metadata databases after a successful migration.

   **Warning:**

   If you started the migration with `reversible` set to `true`, you cannot [reverse](https://www.mongodb.com/docs/mongosync/current/reverse-sync.md#std-label-c2c-reverse-process) the migration after you drop the metadata databases.

   In `mongosh`, drop each metadata database on the destination cluster:

   ```javascript
   use <database-name>
   db.dropDatabase()
   ```

## Behavior

### canWrite and COMMITTED

`mongosync` permits writes on the destination cluster at an earlier stage than the `COMMITTED` state.

You can write to the destination after `/progress` reports `canWrite: true` or when the state is `COMMITTED`. To learn more about write blocking, see [Write Blocking](https://www.mongodb.com/docs/mongosync/current/reference/mongosync-behavior.md#std-label-c2c-write-blocking). If you are running multiple instances of `mongosync`, only use the `canWrite` status from the first `mongosync` process.

In the initial sync, `mongosync` replicates unique indexes on the source cluster as non-unique indexes on the destination cluster. During commit, the relevant non-unique indexes on the destination cluster are set to `prepareUnique`. When this is done, the `/progress` endpoint begins to return `canWrite:
true`. Collections with `prepareUnique` indexes reject new documents that violate the unique index constraint. `mongosync` then converts the `prepareUnique` indexes into unique indexes. When this is done, `mongosync` changes its state to `COMMITTED`.

**Note:**

The conversion of `prepareUnique` indexes to unique indexes can be resource intensive when syncing large collections. This can result in a long time between the `/progress` endpoint returning `canWrite: true` and `mongosync` reaching the `COMMITTED` state.

Although applications can issue writes once `canWrite:
    true` is returned, operations requiring exclusive locks, such as index builds, can proceed only after the index conversion completes. Additionally, write operations may experience increased latency during this time due to competing resource contention.

## Learn More

- [Verify Data Transfer](https://www.mongodb.com/docs/mongosync/current/reference/verification.md#std-label-c2c-verification)

- [`start`](https://www.mongodb.com/docs/mongosync/current/reference/api/start.md#std-label-c2c-api-start)

- [`commit`](https://www.mongodb.com/docs/mongosync/current/reference/api/commit.md#std-label-c2c-api-commit)

- [`progress`](https://www.mongodb.com/docs/mongosync/current/reference/api/progress.md#std-label-c2c-api-progress)

- [`mongosync` States](https://www.mongodb.com/docs/mongosync/current/reference/mongosync-states.md#std-label-c2c-states)
