Backup & Restore
Disks fail, laptops get stolen, and sooner or later someone runs deleteMany({}) on the wrong collection. A backup is a copy of your data that you can bring back after such an accident, and a backup only counts if you have actually tested restoring it. For a shop, losing a day of orders means losing money and customer trust.
In this lesson you will dump the shop database to files, restore it (also under a new name), export collections to JSON and CSV for other tools, and learn how backups work on Atlas and on larger deployments. Start with freshly loaded data.
The MongoDB Database Tools
The command-line backup programs are a separate download called the MongoDB Database Tools, available from mongodb.com/try/download/database-tools (on Linux they also come from MongoDB's package repository). They are not mongosh commands: you run them in a normal terminal or PowerShell window.
| Tool | Purpose | Format |
|---|---|---|
mongodump | Back up databases or collections | BSON files, keeping every type exactly |
mongorestore | Load a mongodump backup | BSON |
mongoexport | Export one collection for other programs | JSON or CSV |
mongoimport | Import JSON or CSV into a collection | JSON or CSV |
Each tool takes the server address with --uri, using the same connection string as mongosh. On a server with access control, use a user that has the backup role for dumping and the restore role for restoring, as described in Security: Users, Roles & Network Access.
Dump a database with mongodump
Back up the whole shop database into a folder named after today's date:
mongodump --uri="mongodb://127.0.0.1:27017" --db=shop --out=backups/2026-10-302026-10-30T15:40:12.118+0530 writing shop.orders to backups/2026-10-30/shop/orders.bson 2026-10-30T15:40:12.121+0530 writing shop.products to backups/2026-10-30/shop/products.bson 2026-10-30T15:40:12.123+0530 writing shop.customers to backups/2026-10-30/shop/customers.bson 2026-10-30T15:40:12.130+0530 done dumping shop.orders (12 documents) 2026-10-30T15:40:12.131+0530 done dumping shop.products (10 documents) 2026-10-30T15:40:12.132+0530 done dumping shop.customers (8 documents)
The tool logs each collection it writes, and the order of the lines can differ between runs. For every collection it creates two files: a .bson file with the documents and a .metadata.json file with the collection's options and index definitions. Indexes are not copied as data; mongorestore rebuilds them from the metadata.
Useful options:
--collection=ordersdumps only one collection (together with--db).--query='{ "status": "delivered" }'dumps only matching documents of that collection.--archive=shop-2026-10-30.archivewrites everything into a single file instead of a folder, which is easier to copy or upload.--gzipcompresses the output, which often makes it several times smaller.
A compressed single-file backup is the most common choice for scheduled jobs:
mongodump --uri="mongodb://127.0.0.1:27017" --db=shop --archive=shop-2026-10-30.archive --gzipRestore with mongorestore
Pretend the worst has happened and the orders collection was emptied by mistake. mongorestore loads a backup back into the server. --drop deletes each collection before restoring it, so you get exactly the backed-up state instead of a mix of old and new documents:
mongorestore --uri="mongodb://127.0.0.1:27017" --drop backups/2026-10-302026-10-30T15:52:40.511+0530 preparing collections to restore from 2026-10-30T15:52:40.540+0530 restoring shop.orders from backups/2026-10-30/shop/orders.bson ... 2026-10-30T15:52:40.612+0530 30 document(s) restored successfully. 0 document(s) failed to restore.
(Some lines are left out.) The final line is the one to check: 8 customers, 10 products and 12 orders make 30 documents. Without --drop, documents whose _id already exists are reported as failures and skipped, which is a common surprise.
You can restore selectively and under a different name, which is the safest way to recover a few documents without overwriting live data:
mongorestore --uri="mongodb://127.0.0.1:27017" --gzip --archive=shop-2026-10-30.archive --nsInclude="shop.orders" --nsFrom="shop.*" --nsTo="shop_restore.*"This restores only the orders, into a new database shop_restore. You can then inspect them in mongosh and copy back just the documents you need.
Export and import JSON and CSV
mongoexport and mongoimport are for exchanging data with spreadsheets, other databases or other teams, not for backups. The accounts team wants a stock sheet:
mongoexport --uri="mongodb://127.0.0.1:27017" --db=shop --collection=products --type=csv --fields=_id,name,category,price,stock --out=stock.csv
mongoimport --uri="mongodb://127.0.0.1:27017" --db=shop --collection=suppliers --file=suppliers.json --jsonArrayThe CSV opens in any spreadsheet. The second command loads a file holding a JSON array of supplier documents into a new suppliers collection. Without --type=csv, mongoexport writes one JSON document per line in Extended JSON, which keeps dates as { "$date": ... } so they can be imported again as real dates. CSV has no types at all: everything comes back as text or plain numbers, and indexes are never included. That is why mongodump is the tool for backups.
Consistent backups of busy servers
While mongodump reads collection after collection, the application keeps writing, so a dump of a busy server may contain an order without the matching stock change. On a replica set, add --oplog to mongodump: it also records the changes made during the dump, and mongorestore --oplogReplay applies them, giving a copy consistent to the moment the dump finished.
For large databases, dumping and restoring every document is slow. Bigger deployments use filesystem or cloud snapshots of a replica set member, or MongoDB's management tools (Ops Manager and Cloud Manager) for continuous backup.
A backup plan that works
- Automate it. Schedule
mongodump --archive --gzipwith Task Scheduler on Windows orcronon Linux, with the date in the file name. - Keep copies elsewhere. Follow the 3-2-1 rule: three copies, on two kinds of storage, one off-site (for example in cloud storage in another region).
- Delete old backups on a schedule, keeping, say, daily copies for two weeks and monthly copies for a year.
- Protect the files. A backup contains every customer's data; encrypt it and restrict who can read it.
- Test restores. Every month, restore the latest backup into a separate database or server and check the counts. An untested backup is only a hope.
Note that mongodump and mongoexport do not decrypt fields protected with Queryable Encryption; those fields stay encrypted in the backup, which is usually what you want.
Common mistakes
- Using
mongoexportfor backups. It loses types such as dates and decimals (CSV) and never includes indexes. Usemongodump. - Restoring without
--dropinto existing data. Documents with existing_idvalues are skipped, leaving a mixture. - Running the tools inside
mongosh. They are separate programs for the operating system's terminal. - Never testing a restore. Many teams discover a broken backup only on the day they need it.
Key points
mongodumpandmongorestore(part of the separate Database Tools) back up and restore data as BSON, with index definitions.--archiveand--gzipproduce a single compressed backup file;--dropmakes a restore replace existing collections.--nsInclude,--nsFromand--nsTorestore selected collections, optionally under a new name.mongoexportandmongoimportexchange JSON or CSV with other tools; they are not backups.- Use
--oplogon replica sets for consistent dumps, and snapshots or Atlas backups for large or critical data. - Automate backups, keep off-site copies, protect them and test restores regularly.
Exercise
Write the commands to (1) back up only the orders collection of the shop into a compressed archive file, (2) restore that archive into a new database called orders_check without touching shop, and (3) export the delivered orders' _id, customerId and total to a CSV file.
Show solution
mongodump --uri="mongodb://127.0.0.1:27017" --db=shop --collection=orders --archive=orders.archive --gzip
mongorestore --uri="mongodb://127.0.0.1:27017" --gzip --archive=orders.archive --nsFrom="shop.*" --nsTo="orders_check.*"
mongoexport --uri="mongodb://127.0.0.1:27017" --db=shop --collection=orders --query='{ "status": "delivered" }' --type=csv --fields=_id,customerId,total --out=delivered.csvThe dump contains only shop.orders. The renaming options send it to orders_check.orders, so the live shop database is untouched; restore tests should always work like this. The CSV has a header row and seven rows, one per delivered order. On Windows, quoting JSON on the command line is awkward; you can save the filter in a file and pass --queryFile=delivered.json instead of --query.
Quick Quiz
1. Which tool should you use for a full backup that keeps dates, decimals and indexes?
mongodump writes BSON with every type preserved and saves index definitions in metadata files.
2. What does --drop do in mongorestore?
Dropping first makes the restored collection match the backup exactly.
3. Why add --oplog when dumping a busy replica set?
The oplog entries recorded during the dump are replayed with --oplogReplay on restore.
4. What is the most important step that many backup plans skip?
A backup you have never restored may be incomplete or broken without anyone knowing.
Learn MongoDB with a mentor
Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
