Back to blog

// OSSeva Blog

Migration

MongoDB 7 to 8 Upgrade: The Path From 6.0 and 7.0 to 8.0, and On to 9.0

Randall McClure10 min read

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

FromToSupported?Way back
6.07.0Yes, with FCV "6.0" set firstCommunity: restore from backup. Binary downgrade not supported
6.08.0No. Go through 7.0
7.08.0Yes, with FCV "7.0" set firstCommunity: restore from backup. Binary downgrade not supported
7.09.0No. Go through 8.0
8.0 or 8.39.0Yes, with FCV "8.0" or "8.3" set firstDocumented 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 config database 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, setFeatureCompatibilityVersion fails without confirm: true. Search upgrade scripts for the command.
  • Journal options are gone. storage.journal.enabled, --journal and --nojournal were removed because journaling is always on. Search every mongod.conf, service unit and container entrypoint for journal and remove them.
  • Free monitoring is decommissioned, and automatic chunk splitting is no longer performed, so sh.enableAutoSplit() and sh.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.0What breaksHow to detect it
Per-operation memory limit: 1 GB or 20% of the memory available to the server, whichever is greaterLarge queries fail with ExceededMemoryLimit or QueryExceededMemoryLimitNoDiskUseAllowedReplay the heaviest aggregations and reports against a 9.0 test replica
Concurrent multi-document transactions capped by maxConcurrentMultiDocumentTransactions, default 10000New transactions rejected with TooManyOpenTransactionsPeak 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 errorSearch for those operators; servers whose host time zone is not UTC are the exposed ones
No server-side JavaScript on ppc64leThose operators stop working on that architectureuname -m on each host
Time series collections stored as a single namespaceDatabases with more than 5,000 time series collections take longer to upgrade and can see write latency spikesdb.getCollectionInfos({ type: "timeseries" }).length per database
Queryable Encryption prefix, suffix and substring queries are GA and incompatible with the 8.2 previewPreview collections must stay on 8.2 or 8.3 or be migratedEncrypted 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 roleHand-written getMore loops that do not resumeChange stream consumers that do not use a driver's resume logic
$group rejects accumulators with an empty field name; renamed serverStatus metrics; mongocryptd deprecatedPipelines and dashboardsSearch 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:

  1. Confirm every member is on the previous release with FCV set to it, and none is in ROLLBACK or RECOVERING.
  2. Upgrade the secondaries one at a time. Shut each down, replace the binary, start it, and wait for SECONDARY:
    db.adminCommand( { shutdown: 1 } )
  3. Step down the primary with rs.stepDown(), wait for a new primary, then upgrade the old one the same way.
  4. 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.
  5. Raise the FCV on the primary, with no initial sync running:
    db.adminCommand( { setFeatureCompatibilityVersion: "8.0", confirm: true } )
    Use "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 $convert to turn an object into binData), set FCV back to "8.0" with confirm: 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

MongoDBMongoDB 8.0MongoDB 9.0UpgradefeatureCompatibilityVersion

Ready to get your open source under control?

Talk to an OSSeva engineer about CVE coverage, compliance, and migration support for your stack.