How to back up and restore MongoDB with mongodump and mongorestore
Run mongodump --archive=backup.archive.gz --gzip to write a whole MongoDB deployment to one compressed file, and mongorestore --archive=backup.archive.gz --gzip to load it back. On a replica set, add --oplog so the dump reflects a single moment. MongoDB describes mongodump as a tool for small deployments; large sharded clusters need snapshot-based backups.
Before you start
mongodump and mongorestore ship in the MongoDB Database Tools package, versioned separately from the server (100.x). Run them from the system shell, not from mongosh. Use the same tools version for dump and restore; the docs warn that mixing versions can fail or restore data incorrectly.
If access control is on, create a user with the built-in backup role for dumps and restore for restores. In mongosh:
use admin
db.createUser({
user: "backup",
pwd: passwordPrompt(),
roles: [ { role: "backup", db: "admin" }, { role: "restore", db: "admin" } ]
})Keep the password off the command line
--uri takes a connection string. A password inside it can be visible to other users through ps. Since Database Tools 100.3.0, --config reads the URI or password from a YAML file instead, which MongoDB recommends.
uri: mongodb://backup:[email protected]:27017/?authSource=adminchmod 600 /root/.mongodump.yamlauthSource=admin says the user lives in the admin database. If the password contains any of $ : / ? # [ ] @, percent-encode those characters (@ becomes %40).
Dump everything to one archive
mongodump --config=/root/.mongodump.yaml --archive=/var/backups/mongodb/full.archive.gz --gzip--archive=FILEwrites a single file instead of adump/directory of BSON files. With no file name it writes to standard output, so you can pipe it.--gzipcompresses the archive. Without--archive, it compresses each file in the directory instead.- With no
--db, mongodump dumps every database exceptlocal.
The dump holds documents and index definitions, not index data. mongorestore rebuilds the indexes after loading the documents, which takes time on large collections.
Use --oplog on a replica set
Without --oplog, writes that happen during the dump leave it inconsistent: early collections reflect one moment, later ones another. --oplog also records the oplog entries written while the dump runs, so a restore with --oplogReplay brings everything to the moment the dump finished.
mongodump --config=/root/.mongodump.yaml --oplog --archive=/var/backups/mongodb/full.archive.gz --gzip- It needs a replica set member. A standalone server has no oplog.
- It must be a full dump. It fails with
--db,--collection,--queryor--dumpDbUsersAndRoles. - It fails if someone runs
renameCollection, an aggregation with$out, or changes users or roles during the dump. - It does not work on a sharded cluster.
mongodump reads from the primary by default. Add --readPreference=secondary to move the read load to a secondary.
To dump from a secondary or a hidden member without loading the primary, and to keep an eye on the oplog window, see how to back up a MongoDB replica set.
Dump one database or one collection
mongodump --config=/root/.mongodump.yaml --db=shop --collection=orders --archive=orders.archive.gz --gzip--db picks the database and --collection the collection. --excludeCollection=name skips one; repeat it to skip more. --query takes a filter in Extended JSON, in single quotes, and needs --collection.
Restore
mongorestore only inserts. If a document with the same _id already exists, it is not overwritten. To replace collections with the backup's copy, add --drop. It drops each collection in the backup before restoring it, and leaves collections that are not in the backup alone.
mongorestore --config=/root/.mongodump.yaml --drop --oplogReplay --archive=/var/backups/mongodb/full.archive.gz --gzipDrop --oplogReplay if the dump was taken without --oplog. The user needs more than the restore role to replay the oplog; the docs describe a custom role for it.
--nsInclude restores only matching namespaces (database.collection, with * as a wildcard). Use it rather than --db and --collection, which are deprecated when restoring from an archive or directory:
mongorestore --config=/root/.mongodump.yaml --nsInclude="shop.orders" --archive=full.archive.gz --gzip--nsFrom and --nsTo restore under a new name, which lets you load a copy next to the live data. Keep --nsInclude, or every other database in the archive is restored too:
mongorestore --config=/root/.mongodump.yaml --nsInclude="shop.*" --nsFrom="shop.*" --nsTo="shop_restored.*" --archive=full.archive.gz --gzipmongorestore restores four collections at a time by default; change it with -j. Add --stopOnError to halt at the first error. The source and target servers must run the same major version or the same feature compatibility version (FCV).
Verify the backup
--dryRun runs mongorestore without importing any data and prints the summary; add --verbose for detail. It is a quick check, not a substitute for a restore:
mongorestore --config=/root/.mongodump.yaml --dryRun --verbose --archive=full.archive.gz --gzipA real restore proves more. Start a throwaway server on the same major version as production (change the image tag to match), restore into it, and compare document counts. mongorestore ends with a line like N document(s) restored successfully. 0 document(s) failed to restore.
docker run -d --name mongo-restore-test -p 127.0.0.1:27018:27017 mongo:8.0mongorestore --uri="mongodb://127.0.0.1:27018" --archive=full.archive.gz --gzipmongosh "mongodb://127.0.0.1:27018/shop" --quiet --eval "db.orders.countDocuments()"Run the same count against production, then remove the test server with docker rm -f mongo-restore-test.
Run it every night with cron
The script writes to a temporary name and renames it only if mongodump succeeds, then deletes archives older than seven days. Remove --oplog on a standalone server.
#!/usr/bin/env bash
set -euo pipefail
BACKUP_DIR="/var/backups/mongodb"
KEEP_DAYS=7
OUT="$BACKUP_DIR/mongodb-$(date +%Y-%m-%d_%H%M).archive.gz"
mkdir -p "$BACKUP_DIR"
trap 'rm -f "$OUT.partial"' EXIT
mongodump --config=/root/.mongodump.yaml --oplog --gzip --archive="$OUT.partial"
mv "$OUT.partial" "$OUT"
find "$BACKUP_DIR" -name "mongodb-*.archive.gz" -type f -mtime +"$KEEP_DAYS" -delete0 3 * * * root /usr/local/bin/mongo-backup.sh >> /var/log/mongo-backup.log 2>&1Make the script executable with chmod 755, and copy the archives to storage off the server.
When mongodump is the wrong tool
mongodump reads every document through the database. If the data is larger than RAM, it pushes your working set out of memory and slows the application. Restores replay every insert and rebuild every index, so they get slow as data grows.
Sharded clusters are harder. MongoDB's procedure needs MongoDB 7.1 or later (or 7.0.2, 6.0.11, 5.0.22): stop the balancer, lock the cluster with fsyncLock() through mongos, dump, then unlock. Writes stop for the whole dump, and --oplog is not available. For large or sharded deployments, use filesystem or disk snapshots, or a coordinated backup system that keeps transactions consistent across shards.
Common errors
| Problem | Fix |
|---|---|
E11000 duplicate key error during restore | The documents already exist and mongorestore does not overwrite. Add --drop, or restore under a new name with --nsFrom/--nsTo. |
| Authentication failed | Add authSource=admin to the URI when the user was created in admin, and percent-encode special characters in the password. |
--oplog fails on a standalone server | Standalone servers have no oplog. Remove --oplog, or convert the server to a single-member replica set. |
--oplog fails with --db or --collection | --oplog only works on full dumps. Dump everything, or drop --oplog. |
| Restore fails or indexes differ on another server | Match the major version or FCV of the source, and use the same Database Tools version for dump and restore. |
A dump holds everything in the database, so encrypt it before it leaves the server, and decide how long to keep each one with a retention policy.
Frequently asked questions
- Does mongodump lock the database?
- No. It reads through normal queries while the database stays writable. Without --oplog, the dump is not a single point in time, and on large data sets it competes with the application for memory.
- What is the difference between mongodump and mongoexport?
- mongodump writes BSON with index definitions and is meant for backups. mongoexport writes JSON or CSV for moving data into other tools, and MongoDB says it is not a backup tool.
- Can I restore a mongodump backup into a newer MongoDB version?
- The target must run the same major version or the same feature compatibility version as the source. A newer server with its FCV set to the old version qualifies.
- How do I restore a single collection?
- Use mongorestore --nsInclude="db.collection" with the archive or dump directory. Add --drop to replace the existing collection.
How this was checked
Commands, limits and prices were checked against these official pages, on October 3, 2026:
- MongoDB Database Tools: mongodump
- MongoDB Database Tools: mongodump behavior
- MongoDB Database Tools: mongorestore
- MongoDB Database Tools: mongorestore behavior, access and usage
- MongoDB Database Tools: mongorestore examples
- MongoDB Manual: Back Up and Restore with MongoDB Tools
- MongoDB Manual: Back Up a Self-Managed Sharded Cluster with a Database Dump
- MongoDB Manual: Connection Strings