00:00

MongoDB Backup and Restore

Last updated: 18 min read

A database is only as safe as its last working backup. A wrong deleteMany(), a buggy deployment, a failed disk or a ransomware attack can wipe out data in seconds, and the only way back is a copy you made before it happened and can actually restore.

This tutorial covers every practical way to back up and restore MongoDB: the mongodump and mongorestore command-line tools, filesystem snapshots for large databases, and managed backups in MongoDB Atlas. You will also automate nightly backups, secure the credentials they use, and prove that your backups really work by test-restoring them.

Versions used: the examples were written for MongoDB 8.0 with MongoDB Database Tools 100.x and the mongosh shell. The same commands work on MongoDB 6.0 and 7.0.

1. Why Backups Matter: RPO and RTO

Replication protects you from a server going down, but it does not protect you from bad writes. If someone drops a collection on the primary, the drop is copied to every secondary within milliseconds. Only a backup taken earlier can bring that data back.

Typical reasons teams restore from a backup:

  • Human error: an update or delete without the right filter, or a script run against production instead of staging.
  • Application bugs: a new release that corrupts documents for hours before anyone notices.
  • Infrastructure failure: lost disks, a deleted cloud volume or a whole data-centre outage.
  • Security incidents: ransomware or an attacker who deletes data.
  • Copying data: seeding a test environment or moving to a new server or cloud.

Before choosing a backup method, agree on two numbers with your team:

TermQuestion it answersExample target
RPO (Recovery Point Objective)How much recent data can we afford to lose?“At most 15 minutes of orders.”
RTO (Recovery Time Objective)How long can the application be down while we restore?“Back online within 1 hour.”

A nightly mongodump gives an RPO of up to 24 hours. If that is too much, you need point-in-time recovery, which Atlas, Ops Manager and oplog-based backups provide.

2. Backup Methods at a Glance

MongoDB offers several backup methods. Each one suits a different database size and deployment type:

MethodHow it worksBest forPoint-in-time restore
mongodump / mongorestoreReads documents through a normal connection and writes them to BSON filesSmall to medium databases, single collections, migrations, test dataLimited (with --oplog)
Filesystem snapshotTakes a block-level snapshot of the volume that holds the data filesLarge self-managed databasesNo, only to the snapshot time
Cold file copyStops mongod and copies the data directorySmall servers that can accept downtimeNo
MongoDB Atlas Cloud BackupFully managed snapshots, optionally with continuous backupAny cluster running on AtlasYes, with Continuous Cloud Backup
Ops Manager / Cloud ManagerMongoDB's management platform takes continuous backups of self-managed deploymentsLarge self-managed replica sets and sharded clustersYes
Sharded clusters: do not rely on mongodump to back up a production sharded cluster. It cannot capture a consistent point in time across all shards while sharded transactions and chunk migrations are running. Use Atlas, Ops Manager or coordinated filesystem snapshots instead.

3. Installing the MongoDB Database Tools

mongodump, mongorestore, mongoexport, mongoimport and a few other utilities belong to the MongoDB Database Tools package. It has its own version numbers (100.x) and is installed separately from the MongoDB server.

Terminal: install the Database Tools
# macOS (Homebrew)
brew tap mongodb/brew
brew install mongodb-database-tools

# Ubuntu / Debian (after adding the official MongoDB repository)
sudo apt-get update
sudo apt-get install -y mongodb-database-tools

# Windows: download the MSI installer from the MongoDB Download Center,
# then add its "bin" folder to the PATH environment variable.

# Check the installation
mongodump --version
mongorestore --version

You will also use mongosh, the MongoDB Shell, to create sample data and check the results of a restore.

4. Sample Data for This Tutorial

All examples use a small online bookstore database called bookstore with three collections. Run this in mongosh to create it:

mongosh: create the bookstore database
use bookstore

db.books.insertMany([
  { _id: 101, title: "Practical Java Streams",   category: "Java",     price: 499, stock: 40 },
  { _id: 102, title: "Designing Event Systems",  category: "Kafka",    price: 650, stock: 12 },
  { _id: 103, title: "Document Modeling Basics", category: "Database", price: 420, stock: 0  }
])

db.customers.insertMany([
  { _id: "C-1", name: "Aditi Rao",   city: "Pune" },
  { _id: "C-2", name: "Marco Silva", city: "Lisbon" }
])

db.orders.insertMany([
  { customerId: "C-1", items: [101, 103], total: 919, status: "SHIPPED",
    createdAt: ISODate("2026-09-28T10:15:00Z") },
  { customerId: "C-2", items: [102],      total: 650, status: "PENDING",
    createdAt: ISODate("2026-10-02T08:40:00Z") }
])

// Indexes are part of the backup too (as definitions)
db.orders.createIndex({ customerId: 1, createdAt: -1 })
db.books.createIndex({ title: 1 }, { unique: true })

5. Backing Up with mongodump

mongodump connects to a running MongoDB deployment, reads the documents and writes them to BSON files, MongoDB's binary storage format. BSON keeps every data type exactly as stored, including ObjectId, Date and Decimal128. For each collection it also writes a .metadata.json file that holds the index definitions and collection options.

5.1 Connect with a connection string

The recommended way to tell the tools where your database is is the --uri option, which takes the same connection string your application uses:

Terminal: connection examples
# Local server without authentication
mongodump --uri="mongodb://localhost:27017"

# Replica set with a dedicated backup user
mongodump --uri="mongodb://backupAgent@db1.example.com:27017,db2.example.com:27017/?replicaSet=rs0&authSource=admin"

# MongoDB Atlas cluster
mongodump --uri="mongodb+srv://backupAgent@cluster0.abcde.mongodb.net"

If the connection string contains a user name but no password, the tool asks for the password. Section 8 shows how to supply it safely in scripts.

5.2 Back up everything

Without any filter, mongodump backs up every database except local. That includes the admin database, which holds users and roles. By default the files go into a folder called dump in your current working directory:

Terminal
mongodump --uri="mongodb://localhost:27017" --out=/backups/2026-10-18

The --out (or -o) option chooses the output folder. The result has one sub-folder per database:

Backup folder layout
/backups/2026-10-18/
├── admin/
│   ├── system.users.bson
│   ├── system.users.metadata.json
│   └── system.version.bson
└── bookstore/
    ├── books.bson                ← the documents
    ├── books.metadata.json       ← indexes and collection options
    ├── customers.bson
    ├── customers.metadata.json
    ├── orders.bson
    └── orders.metadata.json

5.3 Back up one database or one collection

Terminal
# Only the bookstore database
mongodump --uri="mongodb://localhost:27017" --db=bookstore --out=/backups/bookstore

# Only the orders collection of bookstore
mongodump --uri="mongodb://localhost:27017" --db=bookstore --collection=orders --out=/backups/orders

# The whole bookstore database except a large, unimportant collection
mongodump --uri="mongodb://localhost:27017" --db=bookstore --excludeCollection=page_views

5.4 Back up only matching documents

The --query option exports only the documents that match a filter, which is handy for copying a slice of production data to a test system. The filter is written in Extended JSON, so dates use $date:

Terminal
mongodump --uri="mongodb://localhost:27017" \
  --db=bookstore --collection=orders \
  --query='{ "createdAt": { "$gte": { "$date": "2026-10-01T00:00:00Z" } } }' \
  --out=/backups/october-orders

5.5 Compress the backup and write a single archive file

BSON is not compressed. Two options make backups smaller and easier to move:

  • --gzip compresses every file. Text-heavy collections often shrink to a fraction of their size.
  • --archive=<file> writes the whole backup into one file instead of a folder tree, which is easier to copy, encrypt and upload.
Terminal
# One compressed file for the bookstore database
mongodump --uri="mongodb://localhost:27017" --db=bookstore \
  --gzip --archive=/backups/bookstore_2026-10-18.archive.gz

# Back up several collections in parallel (default is 4)
mongodump --uri="mongodb://localhost:27017" --numParallelCollections=8 --gzip --out=/backups/full
Indexes are not copied as data. mongodump saves only the index definitions. mongorestore rebuilds every index after loading the documents, so restoring a large collection with many indexes can take much longer than the backup did.

6. Restoring with mongorestore

mongorestore reads a folder or archive created by mongodump and inserts the documents into a running deployment. It never updates documents that already exist: if a document with the same _id is already in the collection, that document is skipped and reported as a failure.

6.1 Restore a complete backup

Terminal
# Restore every database found in the backup folder
mongorestore --uri="mongodb://localhost:27017" /backups/2026-10-18

# Without a path, mongorestore looks for ./dump in the current directory
mongorestore --uri="mongodb://localhost:27017"

6.2 Restore only some namespaces

A namespace is database.collection. Use --nsInclude and --nsExclude to choose what to restore; * works as a wildcard. These options replace the older --db and --collection options of mongorestore, which are deprecated.

Terminal
# Only the bookstore database
mongorestore --uri="mongodb://localhost:27017" --nsInclude='bookstore.*' /backups/2026-10-18

# Only the orders collection
mongorestore --uri="mongodb://localhost:27017" --nsInclude='bookstore.orders' /backups/2026-10-18

# Everything except the users stored in admin
mongorestore --uri="mongodb://localhost:27017" --nsExclude='admin.*' /backups/2026-10-18

6.3 Replace existing data with --drop

To make a collection look exactly like the backup, add --drop. It drops each collection that exists in the backup just before restoring it. Collections that are not in the backup are left untouched.

Terminal
mongorestore --uri="mongodb://localhost:27017" --nsInclude='bookstore.orders' --drop /backups/2026-10-18
Check the target first. --drop permanently deletes the current data in those collections. Always confirm which server the --uri points to before you press Enter.

6.4 Restore into a different database name

Restoring next to the live data, instead of over it, is the safest way to recover a few deleted documents. Rename namespaces on the way in with --nsFrom and --nsTo:

Terminal
# Restore the bookstore backup as bookstore_recovered
mongorestore --uri="mongodb://localhost:27017" \
  --nsInclude='bookstore.*' \
  --nsFrom='bookstore.*' --nsTo='bookstore_recovered.*' \
  /backups/2026-10-18

You can then copy back only the documents you need, for example with an aggregation that ends in a $merge stage.

6.5 Restore from a compressed archive

Pass the same --archive and --gzip options that were used for the backup. Use --dryRun together with --verbose to see what would be restored without writing anything:

Terminal
# Preview only
mongorestore --uri="mongodb://localhost:27017" \
  --gzip --archive=/backups/bookstore_2026-10-18.archive.gz --dryRun --verbose

# Real restore
mongorestore --uri="mongodb://localhost:27017" \
  --gzip --archive=/backups/bookstore_2026-10-18.archive.gz

6.6 Copy a database between servers in one step

When --archive has no file name, mongodump writes to standard output and mongorestore reads from standard input. Piping one into the other copies data directly between two deployments without a temporary file:

Terminal
mongodump  --uri="$SOURCE_URI" --db=bookstore --archive --gzip \
| mongorestore --uri="$TARGET_URI" --archive --gzip --nsInclude='bookstore.*'

6.7 Useful mongorestore options

OptionWhat it does
--dropDrops each collection from the backup before restoring it
--nsInclude / --nsExcludeChoose which namespaces to restore (wildcards allowed)
--nsFrom / --nsToRestore into different database or collection names
--noIndexRestoreSkips index creation, which is useful when you plan to build indexes later
--numInsertionWorkersPerCollectionUses more parallel insert workers to speed up large restores
--stopOnErrorStops at the first failed insert instead of continuing
--dryRunRuns all checks and reports the plan without writing data
--oplogReplayReplays the oplog captured with mongodump --oplog (next section)

7. Consistent Backups of a Replica Set

mongodump reads collections one after another, and the application keeps writing while it runs. Without extra steps, the orders collection in your backup can be a few minutes newer than customers.

On a replica set, the --oplog option fixes this. While dumping, mongodump also records every change from the oplog (the replica set's log of writes). During restore, --oplogReplay applies those changes, so all collections end up at the same moment: the time the dump finished.

Terminal
# Back up the whole replica set, reading from a secondary to spare the primary
mongodump --uri="mongodb://db1.example.com,db2.example.com,db3.example.com/?replicaSet=rs0&readPreference=secondary" \
  --oplog --gzip --archive=/backups/rs0_full.archive.gz

# Restore and replay the captured oplog entries
mongorestore --uri="mongodb://restore-host:27017" \
  --oplogReplay --gzip --archive=/backups/rs0_full.archive.gz
  • --oplog works only for a full dump. It cannot be combined with --db or --collection.
  • The oplog must be large enough to cover the whole duration of the dump, or the backup fails.
  • Reading from a secondary keeps the extra load away from the primary that serves your users.

8. Securing Backup Credentials

8.1 Use a dedicated user with backup roles

Do not run backups with an administrator account. MongoDB has two built-in roles made for this job: backup (enough to run mongodump) and restore (enough to run mongorestore).

mongosh: create backup and restore users
use admin

db.createUser({
  user: "backupAgent",
  pwd: passwordPrompt(),            // asks for the password instead of saving it in history
  roles: [ { role: "backup", db: "admin" } ]
})

db.createUser({
  user: "restoreAgent",
  pwd: passwordPrompt(),
  roles: [ { role: "restore", db: "admin" } ]
})

8.2 Keep the password out of the command line

A password typed on the command line appears in the shell history and in process lists that other users on the server can see. Instead, put the connection string and password in a YAML configuration file that only the backup account can read, and pass it with --config:

/etc/mongodb/backup.yaml
uri: mongodb://backupAgent@db1.example.com:27017,db2.example.com:27017/?replicaSet=rs0&authSource=admin
password: "replace-with-a-long-random-secret"
Terminal
sudo chmod 600 /etc/mongodb/backup.yaml
mongodump --config=/etc/mongodb/backup.yaml --gzip --archive=/backups/full.archive.gz

8.3 Protect the backup files

  • A backup contains all your data, so protect it as carefully as the database itself.
  • Encrypt archives before sending them off the server, or store them in a bucket with server-side encryption enabled.
  • Restrict who can read, and especially who can delete, the backup storage. Write-once (immutable) storage helps against ransomware.

9. Filesystem Snapshots for Large Databases

For databases of hundreds of gigabytes or more, mongodump becomes slow, and so does rebuilding every index during restore. A filesystem snapshot copies the data files at the block level in seconds, whatever the database size. LVM on Linux, Amazon EBS snapshots and Azure or Google Cloud disk snapshots all work this way.

9.1 Taking a consistent snapshot

With the default WiredTiger storage engine, a snapshot is consistent as long as the journal and the data files are on the same volume. If they are on different volumes, or you are not sure, pause writes while the snapshot is created:

mongosh + Terminal: snapshot with writes paused
# 1. In mongosh, connected to a secondary: flush to disk and block writes
db.fsyncLock()

# 2. In a terminal: create the snapshot (LVM example)
sudo lvcreate --size 20G --snapshot --name mongo-snap-20261018 /dev/vg0/mongodb

# 3. Back in mongosh: allow writes again, as soon as possible
db.fsyncUnlock()

Take the snapshot on a secondary so the primary keeps serving writes, and keep the locked period as short as you can. Afterwards, copy the snapshot to separate storage, because a snapshot on the same disk does not survive the loss of that disk.

9.2 Restoring from a snapshot

  1. Stop the mongod process.
  2. Replace the contents of the data directory (dbPath) with the files from the snapshot.
  3. Start mongod. For a replica set, restore one member and let the others resync from it, or follow MongoDB's documented procedure for restoring a replica set from a backup.
Cold backup alternative: on a small server that can accept a short outage, simply stop mongod, copy the whole data directory, and start it again. A copy taken while mongod is running and not locked is not a safe backup.

10. Backups in MongoDB Atlas

If your database runs on MongoDB Atlas, the managed cloud service, you usually do not need your own backup scripts. Dedicated Atlas clusters include Cloud Backup, which takes snapshots automatically using the storage features of the underlying cloud provider.

  • Snapshot schedule and retention: choose how often snapshots run (hourly, daily, weekly, monthly) and how long each kind is kept.
  • Continuous Cloud Backup: also records the oplog, so you can restore the cluster to any chosen minute within the restore window. This gives point-in-time recovery with a very small RPO.
  • Restore targets: restore a snapshot into the same cluster or into another cluster, which is useful for testing or for creating a copy of production.
  • Multi-region copies: keep snapshot copies in other regions to survive a regional outage.
  • Backup Compliance Policy: stops anyone, including project owners, from deleting backups or shortening retention, which protects against both mistakes and attacks.

You can manage all of this in the Atlas UI, with the Atlas CLI or through the Atlas Administration API. mongodump also works against Atlas when you need a portable copy of a single database or collection.

For self-managed deployments that need the same continuous, point-in-time backups, MongoDB provides Ops Manager (installed in your own data centre) and Cloud Manager (hosted by MongoDB).

11. Automating Nightly Backups

A backup that depends on someone remembering to run it will eventually be missed. The script below takes a compressed, consistent backup, copies it off the server and deletes local copies older than 14 days:

/opt/scripts/mongo-nightly-backup.sh
#!/usr/bin/env bash
set -euo pipefail

BACKUP_DIR="/var/backups/mongodb"
STAMP="$(date +%Y-%m-%d_%H%M)"
FILE="$BACKUP_DIR/rs0_${STAMP}.archive.gz"
KEEP_DAYS=14

mkdir -p "$BACKUP_DIR"

# 1. Consistent, compressed backup of the whole replica set
mongodump --config=/etc/mongodb/backup.yaml --oplog --gzip --archive="$FILE"

# 2. Keep a second copy somewhere else (object storage in another account/region)
aws s3 cp "$FILE" "s3://example-db-backups/mongodb/"

# 3. Remove local backups older than KEEP_DAYS days
find "$BACKUP_DIR" -name 'rs0_*.archive.gz' -mtime +"$KEEP_DAYS" -delete

echo "$(date -Is) backup completed: $FILE"

Schedule it with cron to run every night at 02:30, and send the output to a log file:

crontab -e
30 2 * * * /opt/scripts/mongo-nightly-backup.sh >> /var/log/mongo-backup.log 2>&1

Because the script uses set -e, it stops at the first failed step. Connect the log to your monitoring so that a failed or missing backup raises an alert. Nobody should discover it during an emergency.

Follow the 3-2-1 rule: keep at least 3 copies of your data, on 2 different types of storage, with 1 copy off-site, in a different location or cloud account.

12. Testing Your Backups

A backup you have never restored is only a hope. Test restores regularly, ideally automatically, on a throw-away server. Docker makes this quick:

Terminal: test-restore into a temporary MongoDB 8.0 container
# 1. Start an empty MongoDB 8.0 server on port 27018
docker run -d --name restore-test -p 27018:27017 mongo:8.0

# 2. Restore the latest backup into it
mongorestore --uri="mongodb://localhost:27018" --gzip \
  --archive=/var/backups/mongodb/rs0_2026-10-18_0230.archive.gz

# 3. Check document counts and indexes
mongosh "mongodb://localhost:27018/bookstore" --quiet --eval '
  printjson({
    books:     db.books.countDocuments(),
    customers: db.customers.countDocuments(),
    orders:    db.orders.countDocuments(),
    orderIndexes: db.orders.getIndexes().map(i => i.name)
  })'

# 4. Remove the test server
docker rm -f restore-test

Compare the numbers with production (or with counts saved at backup time). Also time the restore: the time it takes is your real RTO, and it is often much longer than people expect because of index builds.

13. mongodump vs mongoexport

mongoexport and mongoimport look similar but are meant for exchanging data with other tools, not for backups:

Featuremongodump / mongorestoremongoexport / mongoimport
File formatBSON (binary)JSON or CSV (text)
Data typesPreserved exactlyJSON keeps types only as Extended JSON; CSV loses them
Indexes and collection optionsIncludedNot included
ScopeWhole deployment, databases or collectionsOne collection at a time
Users and rolesCan be includedNo
Typical useBackups, restores, migrationsReports, spreadsheets, loading data from other systems

14. Best Practices

  • Choose the method by size and deployment: mongodump for small and medium data, snapshots or Ops Manager for large self-managed data, and Cloud Backup on Atlas.
  • Back up from a secondary so that backups do not slow down the primary.
  • Use --oplog for full backups of a replica set to get a consistent result.
  • Compress and use archives (--gzip --archive) to save storage and simplify copying.
  • Use a dedicated user with only the backup or restore role, and keep passwords in a protected --config file.
  • Store copies off the server, encrypted, in another location, following the 3-2-1 rule.
  • Automate and monitor every backup job, and alert on failures.
  • Test restores on a schedule and measure how long they take.
  • Keep the Database Tools up to date and use a version that supports your server version.
  • Document the restore procedure so anyone on the team can follow it under pressure.

15. Common Mistakes to Avoid

  • Treating replication as a backup. Deletes and bad updates are replicated to every member instantly.
  • Keeping backups on the same disk or server as the database. One failure then destroys both.
  • Restoring with --drop against the wrong server. Double-check the connection string, especially in scripts.
  • Restoring over live data to recover a few documents. Restore into a separate database with --nsFrom / --nsTo and copy back only what you need.
  • Using mongodump for a busy sharded cluster, which cannot give a consistent backup across shards.
  • Forgetting the admin database, and with it all users and roles, when backing up single databases.
  • Copying the data directory of a running mongod without a snapshot or fsyncLock().
  • Never testing a restore until the day it is needed.

16. Summary

  • mongodump writes BSON backups of a whole deployment, single databases, collections or filtered documents. mongorestore loads them back and rebuilds the indexes.
  • Use --gzip and --archive for compact single-file backups, --nsInclude, --nsFrom and --nsTo for targeted restores, and --drop only when you really want to replace data.
  • On replica sets, combine --oplog and --oplogReplay for consistent backups, and run them against a secondary.
  • Large self-managed databases are better served by filesystem snapshots or Ops Manager. On Atlas, Cloud Backup with continuous backup gives point-in-time recovery.
  • Secure, automate, copy off-site and regularly test-restore your backups. That is what turns a backup file into real protection.