What's New in MongoDB 8 & 9.0

MongoDB · Lesson 27 of 28 9 min read Updated

MongoDB 9.0 was released at the end of September 2026. It is the newest major release, and it also brings everyone who upgrades from 8.0 the features that appeared in the minor releases 8.1, 8.2 and 8.3. Knowing what changed helps you read release notes, choose a version for a project and recognise new syntax in other people's code.

This lesson summarises the changes that matter most to developers, from MongoDB 8.0 (October 2024) to 9.0, and explains how MongoDB's version numbers work. Facts here come from MongoDB's official release notes; performance figures are MongoDB's own measurements and vary by workload.

How MongoDB versions work

Release typeExamplesWhat it means
Major release7.0, 8.0, 9.0About every two years, supported for five years; the safe choice for most self-managed servers
Minor release8.1, 8.2, 8.3New features between majors; since 8.2 also available for self-managed servers, but each is only patched until the next one appears
Patch release9.0.4Bug and security fixes for a release series; always install the latest patch

Atlas lets dedicated clusters either stay on a major version or follow the latest release automatically; Free clusters are upgraded by Atlas. To check which version you are running, use db.version().

MongoDB 8.0 (October 2024)

MongoDB 8.0 focused on speed and on scaling more easily. MongoDB reported up to 36% better read throughput and up to 20% faster concurrent writes during replication compared with 7.0. Developer-facing changes include:

  • bulkWrite across collections. A new database command (in mongosh, db.getMongo().bulkWrite()) performs inserts, updates and deletes on several collections in one request, as mentioned in Upserts & Bulk Writes.
  • sort for updateOne() and replaceOne(). You can choose which matching document is changed without findOneAndUpdate().
  • Query settings. setQuerySettings attaches settings, such as which index to use, to a query shape on the server, without changing application code. Older index filters are deprecated in favour of it.
  • defaultMaxTimeMS. A cluster-wide default time limit for read operations, so a runaway query cannot run forever.
  • Express query path. Simple lookups such as _id equality skip normal planning and show EXPRESS_IXSCAN and similar stages in explain().
  • New conversions. $convert converts between strings and binary data, and $toUUID turns a string into a UUID.
  • Queryable Encryption range queries ($lt, $gt and friends) on encrypted fields.
  • Sharding. moveCollection moves an unsharded collection to another shard, unshardCollection reverses sharding, resharding got much faster, and a config server can also hold data as a config shard.

The sort option is a small change you will use often. Flag the oldest pending order for priority handling:

MongoDB Shell
db.orders.updateOne({ status: 'pending' }, { $set: { priority: true } }, { sort: { date: 1 } })
db.orders.find({ priority: true }, { date: 1 })
Output
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}
[ { _id: 1010, date: ISODate('2026-10-11T13:00:00.000Z') } ]

Farhan's order 1010 (11 October) is older than Aarav's 1011 (19 October), so it was chosen.

MongoDB 8.1 and 8.2

  • New $group accumulators: $concatArrays joins arrays from every document of a group, and $setUnion combines them without duplicates.
  • validationAction: 'errorAndLog' rejects invalid writes and also records them in the log, covered in Schema Validation with $jsonSchema.
  • Search and Vector Search for self-managed servers arrived as a public preview with 8.2, and became generally available for Community and Enterprise in 2026, as described in Atlas Search & Vector Search.
  • Queryable Encryption previewed prefix, suffix and substring queries on encrypted text.
  • Operations: the WiredTiger cache size can be set as a percentage of memory, and 8.2 is the first minor release offered for self-managed servers.

Here is $setUnion as an accumulator, collecting every tag used in the Accessories category. $sortArray (available since 5.2) then puts the tags in order, because a union has no fixed order:

MongoDB Shell
db.products.aggregate([
  { $match: { category: 'Accessories' } },
  { $group: { _id: '$category', allTags: { $setUnion: '$tags' } } },
  { $set: { allTags: { $sortArray: { input: '$allTags', sortBy: 1 } } } }
])
Output
[
  {
    _id: 'Accessories',
    allTags: [
      'cable',    'computer',
      'gaming',   'mobile',
      'office',   'video',
      'wireless'
    ]
  }
]

(mongosh prints arrays of more than six short values in columns to save space.) Before 8.1 you needed $push, $unwind and a second $group to do the same.

MongoDB 8.3 (May 2026)

MongoDB 8.3 added many aggregation expressions:

  • $createObjectId creates new ObjectIds inside pipelines and pipeline updates.
  • $hash and $hexHash hash strings or binary data with MD5, SHA-256 or XXH64.
  • $serializeEJSON and $deserializeEJSON convert between BSON and Extended JSON.
  • $subtype returns the subtype of binary data.
  • $map, $filter and $reduce gained arrayIndexAs, and the $$IDX variable gives the current element's position.
  • $toString accepts objects and arrays, $convert accepts a base (2, 8, 10 or 16), and $toArray and $toObject parse strings.
  • $scoreFusion, for combining search results, became generally available.

Under the hood, the query planner gained a cost-based ranker that estimates plan costs when a short trial run cannot pick a winner, which MongoDB reports improves throughput and tail latency for many queries. For sharded clusters, removeShard was deprecated in favour of new shard-draining commands.

MongoDB 9.0 (September 2026)

Performance. Compared with 8.0, MongoDB reports up to 35% faster single-document finds, up to 30% faster single-document updates, up to 20% higher transaction throughput and nearly double the throughput on large deployments, based on its internal testing.

Safety and resource limits.

  • Each operation now has a memory limit (by default 1 GB or 20% of server memory, whichever is greater), so one huge query cannot exhaust the server. The existing 100 MB per-stage limit with spilling to disk is unchanged.
  • At most 10,000 multi-document transactions can be open at once by default (maxConcurrentMultiDocumentTransactions); beyond that, new ones fail with TooManyOpenTransactions.
  • The server now validates every incoming BSON object by default, and the old net.wireObjectCheck setting is deprecated.

Data rules and queries.

  • A new validationLevel: 'constraint' guarantees that every document in a collection satisfies its validator.
  • find, distinct and aggregate accept a querySettings document for one execution, alongside persistent query settings, and query shapes can be given their own maxTimeMS.
  • $queryStats now also covers inserts, updates and deletes, sampling 1% of operations by default.
  • $group now returns an error for an accumulator with an empty field name.

Server-side JavaScript returns. $where, $function and $accumulator, deprecated in 8.0, are no longer deprecated. They run on a new WebAssembly-based engine and evaluate dates in UTC. They are not available on the ppc64le platform, and native operators are still faster.

Time series. Time series collections are now stored as a single namespace and can be renamed with renameCollection.

Security. Queryable Encryption prefix, suffix and substring queries are generally available, so encrypted text fields can be searched by partial matches. The separate mongocryptd process is deprecated in favour of the Automatic Encryption Shared Library.

Ecosystem. MongoDB also announced an extension for Hibernate ORM so Java developers can use familiar Hibernate APIs with MongoDB. Some 9.0 announcements, such as Intelligent Workload Management and OpenTelemetry streaming, are Atlas features rather than server features.

Upgrading safely

Upgrades happen in two steps. First you replace the server binaries (on a replica set, one member at a time, secondaries first). Then, once everything runs well, you raise the feature compatibility version (FCV), which switches on features that change data on disk. Until then you can still go back to the old binaries. Check the FCV like this:

MongoDB Shell
db.adminCommand({ getParameter: 1, featureCompatibilityVersion: 1 })
Output
{ featureCompatibilityVersion: { version: '9.0' }, ok: 1 }

After upgrading the binaries, db.adminCommand({ setFeatureCompatibilityVersion: '9.0', confirm: true }) completes the upgrade. Read the official compatibility notes for your path first; for example, 9.0 changes some error codes and how certain change streams behave after elections. Upgrade drivers and tools such as mongosh and Mongoose to versions that support the new server, and test the whole application on a copy of production data before upgrading production.

Common mistakes

  • Using a feature on an older server. updateOne() with sort fails on 7.0, and the constraint level needs 9.0. Check db.version() and the Atlas cluster's version (Free clusters currently run 8.0).
  • Running a minor release without a plan to keep upgrading. Each minor release stops receiving patches once the next one appears.
  • Skipping the FCV step, or doing it too early. Raise the FCV only when the new binaries are stable, because it makes downgrading harder.
  • Trusting headline performance numbers blindly. Measure your own workload before and after upgrading.

Key points

  • Major releases (8.0, 9.0) arrive about every two years with five years of support; minor releases (8.1 to 8.3) add features in between.
  • 8.0 brought faster reads, the multi-collection bulkWrite command, sort in updateOne(), query settings, defaultMaxTimeMS and easier sharding.
  • 8.1 to 8.3 added $concatArrays and $setUnion accumulators, errorAndLog, self-managed search, many new expressions and a cost-based plan ranker.
  • 9.0 adds performance gains, per-operation memory limits, default BSON validation, the constraint validation level, per-command query settings and GA Queryable Encryption text queries.
  • Server-side JavaScript ($where, $function, $accumulator) is un-deprecated in 9.0 but native operators remain faster.
  • Upgrade binaries first, raise the FCV later, and update drivers and tools to compatible versions.

Exercise

Your team runs MongoDB 7.0 and wants to move to 9.0. Write a short checklist (five to seven steps) for the upgrade, and name two features from this lesson that would let you simplify existing code once you are on 9.0.

Show solution
Text
1. Read the 8.0 and 9.0 release and compatibility notes; list changes that affect the app.
2. Upgrade drivers, mongosh and Mongoose to versions that support 9.0, and test.
3. Take and test a backup (mongodump or an Atlas snapshot).
4. Upgrade 7.0 -> 8.0: binaries one member at a time, secondaries first, then FCV 8.0.
5. Run the application and monitor for a while.
6. Upgrade 8.0 -> 9.0 the same way, then set FCV 9.0 with confirm: true.
7. Re-run performance and integration tests on production-like data.

The upgrade goes one major version at a time (7.0 to 8.0, then 8.0 to 9.0). Afterwards, findOneAndUpdate() calls that only exist to pick the oldest or newest matching document can become updateOne() with sort, and multi-step pipelines that collect tags with $unwind and a second $group can use the $setUnion or $concatArrays accumulators.

Quick Quiz

1. Which of these is a major MongoDB release?

2. Which version added the sort option to updateOne()?

3. What happened to $where and $function in MongoDB 9.0?

4. What does raising the feature compatibility version do?

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