Backing Up & Restoring MongoDB
A backup is a saved copy of your data that you can use to get back to a working state after a disaster — a crashed disk, a bad deploy, an accidental db.dropDatabase(), or a ransomware attack. MongoDB is a document database (it stores flexible JSON-like records instead of rows and tables), and it ships with two dedicated backup tools: mongodump and mongorestore. This page shows you exactly how to use them on Ubuntu, how to schedule them, and — most importantly — how to test that your backups actually work.
How mongodump works
mongodump connects to a running MongoDB server and writes its data to disk in BSON format. BSON (Binary JSON) is the binary form that MongoDB uses internally to store documents, so a mongodump backup is a faithful, lossless copy of your data — including data types like dates and ObjectIds that plain JSON cannot represent perfectly.
The output is a directory tree. Each database becomes a folder, and each collection (a collection is MongoDB’s equivalent of a table) becomes a .bson file plus a .metadata.json file that records its indexes.
When to use this: mongodump/mongorestore is the right tool for small-to-medium databases (up to roughly tens of GB) and for moving data between servers. When NOT to use it: for very large or busy production clusters, prefer filesystem/volume snapshots or MongoDB’s continuous backup features — mongodump reads the whole dataset and can put load on a live server.
On Ubuntu, these tools are not in the server package. Install the MongoDB Database Tools:
sudo apt update
sudo apt install -y mongodb-database-tools
mongodump --version
Output:
mongodump version: 100.10.0
git version: a1b2c3d4e5f6...
Go version: go1.22.5
Authentication flags
If you enabled authentication (a login system requiring a username and password — covered in MongoDB users & authentication), every dump and restore must log in. The important flags are:
| Flag | Meaning |
|---|---|
-u / --username | The MongoDB user |
-p / --password | That user’s password |
--authenticationDatabase | The database where the user was created — almost always admin |
--host / --port | Where the server is (default localhost:27017) |
--uri | A full connection string instead of separate flags |
Passing
-p secreton the command line leaves your password visible in your shell history and in the process list (ps aux). Omit the value (-p) to be prompted interactively, or store credentials in a--uriread from a0600-permission file.
Taking a full backup
This dumps every database the user can read into a timestamped directory:
mongodump \
--uri="mongodb://localhost:27017" \
-u backupAdmin \
--authenticationDatabase admin \
-p \
--out /var/backups/mongo/full-$(date +%F)
Output:
Enter password:
2026-06-15T02:00:01.114+0000 writing admin.system.users to /var/backups/mongo/full-2026-06-15/admin/system.users.bson
2026-06-15T02:00:01.230+0000 writing shop.products to /var/backups/mongo/full-2026-06-15/shop/products.bson
2026-06-15T02:00:01.488+0000 done dumping shop.products (1452 documents)
Backing up a single database
Use --db to dump just one database, and --gzip to compress every file:
mongodump \
--db shop \
--gzip \
-u backupAdmin --authenticationDatabase admin -p \
--out /var/backups/mongo/shop-$(date +%F)
You can narrow it further with --collection products for a single collection, or --archive=/path/file.archive to write one file instead of a folder tree.
Restoring with mongorestore
mongorestore reads a dump directory (or archive) and writes the documents back into a server. The most common mistake is assuming it deletes existing data first — it does not. By default it inserts documents and skips ones whose _id already exists.
Restore the single-database dump from above:
mongorestore \
--db shop \
--gzip \
-u backupAdmin --authenticationDatabase admin -p \
/var/backups/mongo/shop-2026-06-15/shop
Output:
2026-06-15T09:12:00.501+0000 preparing collections to restore from
2026-06-15T09:12:00.640+0000 restoring shop.products from .../products.bson.gz
2026-06-15T09:12:01.902+0000 finished restoring shop.products (1452 documents, 0 failures)
2026-06-15T09:12:01.903+0000 1452 document(s) restored successfully. 0 document(s) failed to restore.
Two flags change this behaviour:
--drop— drop each collection before restoring it, so the result exactly matches the dump (use this when restoring after corruption).--nsFrom/--nsTo— rename databases or collections during restore, e.g. restoreshopintoshop_test.
mongorestore --gzip --drop --nsFrom 'shop.*' --nsTo 'shop_test.*' \
-u backupAdmin --authenticationDatabase admin -p \
/var/backups/mongo/shop-2026-06-15
mongoexport and mongoimport
mongodump produces BSON that only MongoDB understands. When you need human-readable JSON or CSV — for a report, a spreadsheet, or feeding data to another tool — use mongoexport and mongoimport instead.
# Export one collection to JSON
mongoexport --db shop --collection products \
-u backupAdmin --authenticationDatabase admin -p \
--out products.json
# Export selected fields to CSV
mongoexport --db shop --collection products --type=csv \
--fields name,price,sku -p -u backupAdmin --authenticationDatabase admin \
--out products.csv
# Import JSON back
mongoimport --db shop --collection products --file products.json \
-u backupAdmin --authenticationDatabase admin -p
mongoexport/mongoimportare not a faithful backup. JSON cannot represent every BSON type cleanly, so dates and binary fields can change. Use them for data interchange, never as your disaster-recovery copy. For that, always usemongodump.
A scheduled backup script
Create /usr/local/bin/mongo-backup.sh:
#!/usr/bin/env bash
set -euo pipefail
BACKUP_DIR="/var/backups/mongo"
KEEP_DAYS=14
STAMP="$(date +%F_%H-%M)"
URI="mongodb://localhost:27017"
mkdir -p "$BACKUP_DIR"
mongodump \
--uri="$URI" \
-u backupAdmin --authenticationDatabase admin \
-p "$(cat /etc/mongo-backup.pw)" \
--gzip \
--archive="$BACKUP_DIR/all-$STAMP.archive"
# Delete archives older than KEEP_DAYS
find "$BACKUP_DIR" -name 'all-*.archive' -mtime +"$KEEP_DAYS" -delete
Store the password in a locked-down file, make the script executable, then schedule it with systemd or cron:
echo 'your-strong-password' | sudo tee /etc/mongo-backup.pw
sudo chmod 600 /etc/mongo-backup.pw
sudo chmod +x /usr/local/bin/mongo-backup.sh
# Run every night at 02:00 via root's crontab
echo '0 2 * * * /usr/local/bin/mongo-backup.sh >> /var/log/mongo-backup.log 2>&1' \
| sudo tee /etc/cron.d/mongo-backup
See Automating database backups for off-server copies and retention strategy.
Always test your restores
A backup you have never restored is not a backup — it is a hope. Schedule a real restore into a throwaway database and check the document counts match:
LATEST=$(ls -t /var/backups/mongo/all-*.archive | head -1)
mongorestore --gzip --archive="$LATEST" --drop \
--nsFrom '*' --nsTo 'restoretest_*' \
-u backupAdmin --authenticationDatabase admin -p
Then connect with mongosh and run db.products.countDocuments() against the restored copy to confirm the data is intact, and drop the test databases afterwards.
Best Practices
- Use
mongodump --gzip --archivefor compact, single-file backups that are easy to copy off-server. - Never store the password inline in scripts or cron lines — read it from a
chmod 600file owned by root. - Run a dedicated backup user with only the
backupandrestoreroles, not full admin rights. - Copy backups off the database server (S3, another host) — a local backup dies with the disk it lives on.
- Test a restore on a schedule and verify document counts, not just that the command exits 0.
- Use
mongodump/mongorestorefor portability and small datasets; switch to volume snapshots for large, busy clusters.