> For the complete documentation index, see [llms.txt](https://atomic-blend.gitbook.io/mongo2pg/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://atomic-blend.gitbook.io/mongo2pg/operating-a-migration/operations/cutover.md).

# Cutover procedure

The cutover procedure is: **stop writers → `cutover check` → flip the application → keep mongo2pg running read-only for a rollback window → retire it.**

```mermaid
sequenceDiagram
    actor Op as Operator
    participant App as Application
    participant M2P as mongo2pg
    participant Mongo as MongoDB
    participant PG as PostgreSQL

    Op->>App: stop writers (maintenance window / feature flag)
    Note over App,Mongo: mongo2pg keeps streaming the last few<br/>change events during the drain
    Op->>M2P: mongo2pg cutover check
    M2P->>M2P: every collection streaming, lag < maxLagSeconds
    M2P->>PG: zero open quarantine, zero pending_fk
    M2P->>Mongo: re-run count / checksum / sample checks live
    M2P->>PG: VALIDATE every deferred (NOT VALID) foreign key
    alt any condition fails
        M2P-->>Op: exit 4, names the failing condition per collection
        Op->>Op: fix it (see Handling quarantine / Operational realities), retry
    else every condition passes
        M2P-->>Op: exit 0 — safe to switch
        Op->>App: flip the application to PostgreSQL
        Note over M2P,Mongo: mongo2pg keeps streaming, read-only,<br/>for the rollback window
        Op->>M2P: retire (stop the process, decommission the release)
    end
```

## Stop writers

Nothing about mongo2pg enforces this — it is an application-level step. A maintenance window, a feature flag, or scaling the writing service to zero all work. mongo2pg has no code path that writes to MongoDB (read-only credentials enforce this at the database level too), so nothing it does can help or hurt this step.

## `cutover check`

Run it from the same mapping the migration has been running under. A non-zero exit means it is not yet safe, and the output names exactly which condition failed for which collection — see [Verification and checks](/mongo2pg/operating-a-migration/operations/verification-and-checks.md) for the full list the gate evaluates. Fix what it names (often [quarantine](/mongo2pg/operating-a-migration/operations/handling-quarantine.md), sometimes lag or a `NOT VALID` constraint that will not validate) and run it again. It is safe to run repeatedly; it never writes anything to either database beyond `_migration.verify_runs`.

## Flip the application

Point the application's connection strings at PostgreSQL and restart it. This is entirely outside mongo2pg's scope — it does not participate in the flip itself, only in proving beforehand that it is safe.

## Rollback window

Keep the `mongo2pg` process running, read-only, for a window after the flip. It cannot help execute a rollback — there is no reverse sync, and nothing writes back to MongoDB by design — so this window exists purely so MongoDB stays available, unmodified, as a fallback data source if the application flip needs to be reverted by other means. How long that window should be is an operational judgement call specific to each service, not something the tool decides for you.

## Retire

Once the rollback window has passed, stop the `mongo2pg` process (or uninstall the Helm release / tear down the Compose service) and decommission it for that collection set. `_migration.*` and `legacy_mongo_id` columns can be dropped at your convenience once you are confident you will not need them — mongo2pg itself never reads them again after this point.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://atomic-blend.gitbook.io/mongo2pg/operating-a-migration/operations/cutover.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
