DEV Community

Cover image for How to Copy and Sync a Local MongoDB Collection to Atlas
VisuaLeaf
VisuaLeaf

Posted on • Originally published at visualeaf.com

How to Copy and Sync a Local MongoDB Collection to Atlas

Moving data from a local MongoDB database to Atlas usually means exporting files, importing them again, and repeating the same process when something changes.

I wanted to test a simpler way in VisuaLeaf: copy a local collection to MongoDB Atlas and keep the Atlas collection updated automatically.

For this example, I used a local visits collection containing seven documents. The documents included ordinary fields, nested objects, arrays, dates, and ObjectIds, so I could also check whether the original MongoDB structure remained intact in Atlas.

Here is the complete process, followed by an insert, update, and delete test.

What I used

My source and target were:

Role Connection Database Collection
Source Local Replica Set database_compare_demo visits
Target MongoDB Atlas database_compare_demo visits_atlas_sync

I used a different target collection name so I could verify the copied data without mixing it with anything already stored in Atlas.

The local source was a replica set because continuous synchronization relies on MongoDB change streams. Change streams are available for replica sets and sharded clusters, not standalone MongoDB deployments. (MongoDB change streams)

If the source is standalone, the job can still perform an initial copy, but it cannot continue watching for later changes.

The local  raw `visits` endraw  collection before it was copied to Atlas.

The local visits collection before it was copied to Atlas.

Preparing the Atlas connection

Before creating the sync job, I made sure VisuaLeaf could write to my Atlas cluster.

Before using a standard Atlas connection, I configured two access items:

  1. A database user with permission to access the target database.
  2. My computer’s public IP address added to the project’s IP access list.

Atlas database users are separate from the account used to sign in to the Atlas website. For this test, I used a database user with read and write access to database_compare_demo.

I added only my current IP address to the Atlas access list instead of allowing connections from every IP. Atlas only accepts standard client connections from addresses included in that list. (MongoDB Atlas connection prerequisites)

From the Atlas cluster’s *Connect* window, I copied the driver connection string. Its general format was:

mongodb+srv://<username>:<password>@<cluster-host>/
Enter fullscreen mode Exit fullscreen mode

I used that URI to create a connection in VisuaLeaf and named it MongoDB Atlas. I tested the connection before continuing.

Creating the sync job

I opened *Mongo Sync* and created a new job with these details:

Setting Value
Job name Local Visits to Atlas
Description Copy local clinic visits to Atlas and keep later changes synchronized.
Source connection Local Replica Set
Source database database_compare_demo

The source connection showed full change-stream support, which meant I could select Full sync later.

The local replica set and  raw `database_compare_demo` endraw  database selected as the source.

The local replica set and database_compare_demo database selected as the source.

Mapping the local collection to Atlas

In the Rules step, I added the Atlas connection as the target and configured one rule:

Setting Value
Target connection MongoDB Atlas
Target database database_compare_demo
Source collection visits
Target collection visits_atlas_sync
Filter Empty
Transformation None (pass-through)

I left the filter empty because I wanted all seven documents.

I also used *None (pass-through)* instead of generating field mappings. Both sides were MongoDB, so I wanted to preserve each document exactly as it was, including its _id, nested objects, arrays, dates, and optional fields.

Field mappings are useful when renaming fields, changing types, masking values, or sending data into a different schema. They were unnecessary for this direct MongoDB-to-MongoDB copy.

The  raw `visits` endraw  collection mapped to  raw `visits_atlas_sync` endraw  with pass-through documents.

The visits collection mapped to visits_atlas_sync with pass-through documents.

Choosing Full sync

The Options step offered three modes:

Mode What it does When to use it
Initial Only Copies the documents that currently exist, then stops One-time collection copy
Incremental Only Watches only for changes made after the job starts The target is already populated
Full sync Copies existing documents and then watches for later changes Initial copy plus continuous synchronization

I selected *Full sync* and enabled Start sync immediately after creation.

This mode first copies the seven documents already stored locally. After the initial phase finishes, it continues listening for new inserts, updates, and deletes.

Full sync copies existing documents and continues watching the local collection.

Full sync copies existing documents and continues watching the local collection.

Reviewing and launching the job

The Review screen showed:

  • Local Replica Set / database_compare_demo as the source;
  • MongoDB Atlas / database_compare_demo as the target;
  • one rule from visits to visits_atlas_sync;
  • no filter or transformation;
  • Full sync with automatic start.

It also estimated an initial copy of approximately seven documents.

The complete local-to-Atlas configuration before launching the job.

The complete local-to-Atlas configuration before launching the job.

I clicked *Create & launch* and waited for the initial phase to finish. Once the monitor showed that the job was running and waiting for changes, I checked the Atlas collection directly.

The initial copy is complete and the job is monitoring later changes.

The initial copy is complete and the job is monitoring later changes.

Verifying the initial copy in Atlas

I opened database_compare_demo.visits_atlas_sync on the Atlas connection and counted its documents:

db.visits_atlas_sync.countDocuments({})
Enter fullscreen mode Exit fullscreen mode

The result was 7, matching the local source collection.

I also opened several documents and checked their BSON types. The ObjectIds, dates, nested patient and doctor objects, and arrays were preserved because the job used pass-through documents rather than converting them into a new schema.

The initial count proved that the collection was copied. It did not yet prove that the Full sync job would handle later changes, so I tested each main operation separately.

Test 1: Inserting a new local document

I inserted one clearly labeled test visit into the local source:

Insert a new document into the local connection.

Insert a new document into the local connection.

Then I searched for the same visitId in Atlas:

db.visits_atlas_sync.findOne({
  visitId: "VIS-ATLAS-TEST"
})
Enter fullscreen mode Exit fullscreen mode

A new local visit appears automatically in the Atlas collection.

A new local visit appears automatically in the Atlas collection.

The new document appeared in the target collection without restarting or recreating the job. The target count increased from seven to eight.

Test 2: Updating the local document

Next, I updated both a top-level field and a nested field:

db.visits.updateOne(
  { visitId: "VIS-ATLAS-TEST" },
  {
    $set: {
      status: "completed",
      "doctor.roomNumber": "204",
      updatedAt: new Date()
    }
  }
)
Enter fullscreen mode Exit fullscreen mode

I checked the Atlas document again:

Top-level and nested changes from the local document are visible in Atlas.

Top-level and nested changes from the local document are visible in Atlas.

Test 3: Deleting the local document

Finally, I deleted the test document from the local collection:

db.visits.deleteOne({
  visitId: "VIS-ATLAS-TEST"
})
Enter fullscreen mode Exit fullscreen mode

I verified the target one more time:

db.visits_atlas_sync.countDocuments({
  visitId: "VIS-ATLAS-TEST"
})
Enter fullscreen mode Exit fullscreen mode

Deleting the local test document removes its synchronized Atlas copy.

Deleting the local test document removes its synchronized Atlas copy.

The result returned to 0, and the full Atlas collection returned to seven documents.

When this workflow is useful

This type of Mongo Sync job makes sense when I want to:

  • copy selected local collections to an Atlas development or staging environment;
  • keep a cloud copy updated while continuing to write locally;
  • move a collection without repeatedly exporting and importing JSON files;
  • test an application against Atlas using recent local data;
  • synchronize only the collections needed for a specific workflow.

The important word is *selected*. This was a collection-level sync, not a complete production migration.

VisuaLeaf Mongo Sync monitor showing live inserts, updates, and deletes.

Live MongoDB sync from local replica set to Atlas.

How this differs from other Atlas migration methods

MongoDB provides other tools for different jobs:

  • mongodump and mongorestore are useful for a self-managed, one-time transfer using a BSON dump.
  • Atlas Live Migration is designed for moving a deployment into Atlas and managing a production cutover with minimal downtime.
  • This Mongo Sync workflow focuses on copying selected collections and continuing to apply their changes.

Atlas recommends its Live Migration workflow when performing a supported production migration. It uses MongoDB’s mongosync technology underneath and includes a cutover process for redirecting applications to the Atlas destination. (Atlas Live Migration)

I would not present a collection-level sync as a replacement for that process.

What I would still verify before using it in production

This small test verified document copying and three change types. It did not test:

  • high write volume or very large collections;
  • long network interruptions and recovery;
  • schema changes while the job was running;
  • independent writes made to both source and target;
  • users, roles, indexes, validation rules, or other database metadata;
  • a full application cutover from local MongoDB to Atlas.

I treated the local collection as the source of truth and used an empty target collection. That kept the test easy to understand and avoided conflicts with existing Atlas documents.

Final takeaway

The first copy was easy to check: 7 local documents appeared in Atlas.

But the more important part was what happened after that. When I inserted, updated, and deleted a local document, the same changes appeared in Atlas without exporting another file or recreating the job.

Because both sides were MongoDB, I could use pass-through mode and keep the original document structure.

For development, staging, testing, or selected collection sync, this is a practical way to move local MongoDB data to Atlas and keep it updated. For a full production migration, I would still follow MongoDB’s official migration process and plan the cutover separately.

Want to try it?

CTA Image

Download for Free and test Mongo Sync with your own local MongoDB database and Atlas cluster.

References

Top comments (0)