Meteor 3.5 is out: Change Streams and Performance improvements

y7r4m1 pts0 comments

🚀 Meteor 3.5 is out: Change Streams & Performance improvements - releases - Meteor Forum

🚀 Meteor 3.5 is out: Change Streams & Performance improvements

announce

releases

italojs

February 19, 2026, 6:27pm

Meteor 3.5 is Here: Change Streams, Pluggable DDP Transport & Performance

Hello everyone! We’re thrilled to announce that Meteor 3.5 is now officially released . A huge thank you to everyone who tested the betas and release candidates and reported issues along the way — your feedback got us here.

3.5 is heavily focused on MongoDB Change Streams and a new pluggable DDP transport architecture, alongside a long list of performance and quality-of-life improvements.

For a deep dive into the “why” behind Change Streams, check out our detailed discussion here.

Getting started with 3.5

Since 3.5 is now the recommended release, you can get going with the usual commands:

Create a New App

meteor create my-app

You can also pin the release explicitly:

meteor create my-app --release 3.5

Update Your App

meteor update --release 3.5

Change Streams — now on by default

In 3.5, Change Streams are the default reactivity mechanism — you don’t need to do anything to enable them. The minimum requirement is a MongoDB 6+ replica set or sharded cluster . On older MongoDB versions Meteor automatically falls back to oplog or polling.

If you want to roll back to the previous reactivity system, add the following to your settings.json:

"packages": {<br>"mongo": {<br>"reactivity": ["oplog", "polling"]<br>// you can also use ["changeStreams", "oplog", "polling"]<br>// Meteor will try Change Streams first, then oplog,<br>// and if that doesn't work, fall back to polling.

Refer to the docs for further technical details.

ChangeStreams are transparent for you

Once you’re on 3.5, Meteor takes care of the rest automagically

Meteor.publish('links', function () {<br>// This uses Change Streams ONLY for the LinksCollection<br>// and ONLY for documents matching { my: 'query' }<br>return LinksCollection.find({ my: 'query' });<br>});

Different from oplog — which observes ALL changes from a collection whether you use them or not — Change Streams only care about the changes you are actually querying.

Highlights

40% More Scalability with Change Streams (#13787)

The traditional Oplog driver works by tailing all database changes and performing a “diff” process against client-side documents. As connections scale, this architecture hits a critical bottleneck: processing capacity.

In our tests, we discovered that while Oplog manages memory well under normal loads, it struggles to deliver data to clients fast enough during high traffic. This creates a backlog of pending queries and connections that eventually leads to Out of Memory (OOM) crashes.

Change Streams solve this by handling data on-demand (streaming) . Instead of accumulating data locally, it processes it as it flows, allowing the system to maintain stability. Even under extreme stress, the system experiences simple timeouts rather than a fatal process crash.

A nice bonus: Change Streams also unlock real-time reactivity on managed and serverless MongoDB tiers (Atlas Shared, serverless) where oplog access isn’t available — no more being forced into expensive polling.

Preliminary Benchmarks

The following data was captured using an artillery script in a dedicated machine (2 vcpu with 8 GB of RAM) running a standard Meteor app (otel) hosted in galaxy (using premium instance - 1 container of 8 vcpus with 8GB ) with high-frequency add/delete operations:

Oplog: Maxed out at 1200 VUs (10 VUs/s for 120s). Beyond this, the process suffered from persistent timeouts followed by an OOM crash .

Change Streams: Handled up to 1680 VUs (14 VUs/s for 120s). Beyond this, we observed only timeouts, but the process remained stable with no OOM.

Each VU ran 10 connections, one connection each 0.5s doing an insert.

VU = Artillery Virtual User

Conclusion: Change Streams offer a 40% increase in connection capacity and significantly better resilience, effectively eliminating OOM errors caused by high data transfer volume.

(Image from montiAPM)

Reproducing the benchmark

> git clone git@github.com:meteor/performance.git<br>> cd otel<br>> git checkout otel<br>> docker-compose up -d mongo-replica

# edit your settings.json enabling changeStreams or Oplog<br># then run the meteor app

> MONGO_OPLOG_URL="mongodb://localhost:27017,localhost:27018,localhost:27019/local?replicaSet=rs0" MONGO_URL="mongodb://localhost:27017,localhost:27018,localhost:27019/?replicaSet=rs0" METEOR_NO_DEPRECATION=true meteor run --settings ./settings.json --port 8080 --inspect

# in another shell, run the artillery

> npx artillery run tests/artillery/add-task.yml

Pluggable DDP Transport Architecture + uWebSockets (#14231)

DDP now has a pluggable transport layer , letting you pick the right trade-off for your app:

Maximum compatibility with sockjs (the default) for public traffic behind strict proxies.

Lower latency and higher throughput with uws...

meteor change streams oplog performance mongodb

Related Articles