// OSSeva Blog
MigrationMongoDB 7 to 8 Upgrade: The Path From 6.0 and 7.0 to 8.0, and On to 9.0
The short answer
MongoDB upgrades one major release at a time. To reach 8.0 you must be on a 7.0 release, and to reach 7.0 you must be on 6.0, so a 6.0 cluster makes two full upgrades: 6.0 to 7.0, then 7.0 to 8.0. MongoDB 9.0 went GA in September 2026 and accepts upgrades from 8.0 or 8.3, so 8.0 to 9.0 is the third step if you want the newest release. Each step is a rolling upgrade of the binaries followed by setFeatureCompatibilityVersion with confirm: true.
The rollback rules differ by step, and that should shape your plan. MongoDB Community Edition does not support binary downgrades from 7.0 to 6.0 or from 8.0 to 7.0, so for those steps the way back is a restore from backup. From 8.3 onward MongoDB supports single-version downgrades, so 9.0 can step back to the latest 8.0 patch.
Coming from 4.4 or 5.0? Start with upgrading MongoDB 4.4, 5.0 or 6.0 to 7.0 or 8.0, which covers the AVX requirement and the 5.0 and 6.0 changes.
Upgrade paths and dates
| From | To | Supported? | Way back |
|---|---|---|---|
| 6.0 | 7.0 | Yes, with FCV "6.0" set first | Community: restore from backup. Binary downgrade not supported |
| 6.0 | 8.0 | No. Go through 7.0 | |
| 7.0 | 8.0 | Yes, with FCV "7.0" set first | Community: restore from backup. Binary downgrade not supported |
| 7.0 | 9.0 | No. Go through 8.0 | |
| 8.0 or 8.3 | 9.0 | Yes, with FCV "8.0" or "8.3" set first | Documented downgrade to the latest 8.0 (or 8.3) patch |
MongoDB's lifecycle schedule for self-managed server releases: 6.0 reached end of life on 31 July 2025, 7.0 is supported until 31 August 2027, 8.0 and 8.3 until 31 October 2029, and 9.0 until 31 October 2031. A cluster upgraded to 7.0 today has under a year left, so treat 7.0 as a waypoint. See the MongoDB 7.0 end of life and MongoDB 8.0 end of life pages for the detail.
Pre-upgrade checklist
// On every member, in mongosh: binary version and FCV
db.version()
db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
// No member in ROLLBACK or RECOVERING
db.adminCommand( { replSetGetStatus: 1 } ).members.map(m => [m.name, m.stateStr])
// Sharded clusters, through mongos
sh.getBalancerState()
# Transparent Huge Pages on every host (7.0 wants it off, 8.0 and later want it on)
cat /sys/kernel/mm/transparent_hugepage/enabled
- FCV matches the binaries. A cluster that once had its binaries upgraded without the FCV step reports an FCV one release behind, and the next upgrade will not start until that is fixed.
- Drivers. Every upgrade page asks you to confirm that each driver supports the target release, warning that incompatible drivers can produce undefined behaviour. Include batch jobs and reporting tools.
- A backup you have restored. For 6.0 to 7.0 and 7.0 to 8.0 it is your rollback plan, so time the restore.
- Sharded clusters: back up the
configdatabase before you start.
Step 1: 6.0 to 7.0, in brief
The 7.0 changes most likely to break automation are covered with checks in the 4.4 to 7.0 guide. The short version:
- FCV needs confirmation. From 7.0,
setFeatureCompatibilityVersionfails withoutconfirm: true. Search upgrade scripts for the command. - Journal options are gone.
storage.journal.enabled,--journaland--nojournalwere removed because journaling is always on. Search everymongod.conf, service unit and container entrypoint forjournaland remove them. - Free monitoring is decommissioned, and automatic chunk splitting is no longer performed, so
sh.enableAutoSplit()andsh.disableAutoSplit()do nothing.
Step 2: 7.0 to 8.0, and how to detect each change
1. Queries for null no longer match undefined. In 8.0, an equality match on null no longer matches fields that hold the deprecated BSON undefined value, or arrays that contain it. This affects $eq, $in and $lookup. Nothing errors; queries quietly return fewer documents. Find the data before the upgrade:
db.getCollectionNames().forEach(function (c) {
// replace "status" with each field your code queries for null
var n = db.getCollection(c).countDocuments({ status: { $type: "undefined" } });
if (n > 0) print(c + ": " + n);
});
MongoDB's guidance is to remove those fields, update them to null, or change the queries to match undefined explicitly. Recent MongoDB Shell and driver versions convert undefined to null on insert and update, so the values to look for were written by older clients or imported.
2. Commands run directly against a shard are refused. Once a cluster has more than one shard, most commands sent straight to a shard's mongod need the maintenance-only directShardOperations role or have to go through mongos. Detect it by listing maintenance scripts, backup tools and monitoring agents that connect to shard hosts rather than to mongos.
3. Memory allocator and Transparent Huge Pages. 8.0 ships an upgraded TCMalloc with per-CPU caches on x86_64 and ARM64. To use it, MongoDB asks for THP to be enabled on 8.0 hosts, the reverse of the long-standing advice to disable it for 7.0 and earlier. tcmallocReleaseRate also changed meaning and default, and tcmallocAggressiveMemoryDecommit is deprecated. Detect it with the THP check above and a search of your configuration for tcmalloc. Expect memory profiles to change; re-baseline them on a test replica.
4. Monitoring field changes. wiredTiger.concurrentTransactions in serverStatus is now queues.execution, and the metrics.repl.buffer counters were split into write and apply buffers. Dashboards that read the old names go blank rather than fail. Search your monitoring configuration for both.
5. Smaller behaviour changes. majority writes now acknowledge once a majority has written the oplog entry; concurrent compact commands on the same collection return an error; malformed geospatial input is rejected; the storeFindAndModifyImagesInSideCollection parameter is removed. Run the application test suite against an 8.0 replica to catch these.
Step 3: 8.0 to 9.0, and how to detect each change
| Change in 9.0 | What breaks | How to detect it |
|---|---|---|
| Per-operation memory limit: 1 GB or 20% of the memory available to the server, whichever is greater | Large queries fail with ExceededMemoryLimit or QueryExceededMemoryLimitNoDiskUseAllowed | Replay the heaviest aggregations and reports against a 9.0 test replica |
Concurrent multi-document transactions capped by maxConcurrentMultiDocumentTransactions, default 10000 | New transactions rejected with TooManyOpenTransactions | Peak db.serverStatus().transactions.currentOpen |
Server-side JavaScript runs on a WebAssembly engine that evaluates local Date operations in UTC | $where, $function and $accumulator code using getHours() or toString() returns different results, with no error | Search for those operators; servers whose host time zone is not UTC are the exposed ones |
| No server-side JavaScript on ppc64le | Those operators stop working on that architecture | uname -m on each host |
| Time series collections stored as a single namespace | Databases with more than 5,000 time series collections take longer to upgrade and can see write latency spikes | db.getCollectionInfos({ type: "timeseries" }).length per database |
| Queryable Encryption prefix, suffix and substring queries are GA and incompatible with the 8.2 preview | Preview collections must stay on 8.2 or 8.3 or be migrated | Encrypted collections created with the preview query types |
| Change streams with read preference primary or secondary return a resumable error after an election changes the node's role | Hand-written getMore loops that do not resume | Change stream consumers that do not use a driver's resume logic |
$group rejects accumulators with an empty field name; renamed serverStatus metrics; mongocryptd deprecated | Pipelines and dashboards | Search pipelines and monitoring configuration |
The procedure for each step
The same sequence applies to 7.0, 8.0 and 9.0. For a replica set:
- Confirm every member is on the previous release with FCV set to it, and none is in ROLLBACK or RECOVERING.
- Upgrade the secondaries one at a time. Shut each down, replace the binary, start it, and wait for
SECONDARY:db.adminCommand( { shutdown: 1 } ) - Step down the primary with
rs.stepDown(), wait for a new primary, then upgrade the old one the same way. - Run on the new binaries with the old FCV for a burn-in period. MongoDB recommends this because enabling the new features makes any downgrade harder.
- Raise the FCV on the primary, with no initial sync running:
Usedb.adminCommand( { setFeatureCompatibilityVersion: "8.0", confirm: true } )"7.0"or"9.0"for the other steps.
For a sharded cluster, through mongos: back up the config database, run sh.stopBalancer(), upgrade the config server replica set, then each shard replica set, then the mongos instances, run sh.startBalancer(), and set the FCV through mongos.
Repeat the whole sequence for the next step. Do not leave a cluster on new binaries with the old FCV for months: the next upgrade checks the FCV and will not start.
Rollback limits
- Before the FCV change, each step can be reversed by restarting members on the previous binary, because the data files are still compatible. This is what the burn-in period is for.
- 7.0 to 6.0 and 8.0 to 7.0, after the FCV change: MongoDB states that binary downgrades are not supported for Community Edition, and Enterprise downgrades need MongoDB Support. Plan these rollbacks as restores from the backup taken just before the step.
- 9.0 to 8.0: documented. Remove the backward-incompatible 9.0 features (for example, views that use
$convertto turn an object intobinData), set FCV back to"8.0"withconfirm: true, then replace the binaries with the latest 8.0 patch. Downgrades are single-version only, so 9.0 to 8.0 to 7.0 is not possible.
Where OSSeva fits
MongoDB 7.0 and 8.0 are supported upstream, so for those lines the issue is the upgrade work, not patching. OSSeva for MongoDB covers the lines behind them: patched builds of MongoDB Community Server 4.2, 4.4, 5.0 and 6.0, with security fixes backported to mongod, mongos and the bundled tools, signed and with SBOMs. A 6.0 estate stays patched while the 6.0 to 7.0 to 8.0 path is worked through. OSSeva Assure adds the featureCompatibilityVersion upgrade plan and a driver compatibility audit; OSSeva Operate adds 24/7 replica set and cluster monitoring, a 15-minute P1 response and executed major version upgrades. Pricing is per replica set or cluster; book a discovery call for a quote. OSSeva supports self-managed MongoDB, not Atlas.
Frequently asked questions
Can I upgrade MongoDB 6.0 directly to 8.0?
No. Upgrade to the latest 7.0 patch, raise FCV to "7.0", then upgrade to 8.0.
Can I upgrade MongoDB 7.0 directly to 9.0?
No. 9.0 accepts upgrades from 8.0 or 8.3 only. Go to 8.0 first.
Is MongoDB 9.0 released?
Yes. MongoDB 9.0 was released in September 2026 and is supported until 31 October 2031.
Can I downgrade MongoDB 8.0 to 7.0?
Not by swapping binaries on Community Edition once the FCV is 8.0; MongoDB does not support it. Restore from a backup taken before the upgrade, or downgrade before raising the FCV.
Why does setFeatureCompatibilityVersion fail on MongoDB 7.0 and later?
Usually because the command omits confirm: true, which has been required since 7.0.
Should we enable Transparent Huge Pages for MongoDB 8.0?
Yes. MongoDB 8.0 and later ask for THP to be enabled so the new TCMalloc can use it. For 7.0 and earlier the guidance is still to disable it, so change the setting host by host as each member moves to 8.0.
Tags
Related articles
MongoDB vs MySQL vs PostgreSQL: Data Model, Transactions, Scaling, Licensing and Which to Choose
October 8, 2026MigrationPostgreSQL vs Aurora PostgreSQL vs RDS: Architecture, Billing, Version Support and When to Self-Manage
October 8, 2026MigrationSpring Boot vs Quarkus vs Micronaut: Startup, Native Images, Ecosystem, Support and Which to Choose
October 8, 2026Ready to get your open source under control?
Talk to an OSSeva engineer about CVE coverage, compliance, and migration support for your stack.