[EDITED 2x]
Hey everyone! ![]()
I’ve been working on a long-awaited feature: support for MongoDB Change Streams in Meteor!
With this new capability, Meteor can listen to real-time events directly from MongoDB (inserts, updates, deletes, etc.) and use them to power reactivity.
I’ve just opened a PR in our GitHub repo. ![]()
Work status
POC
Oplog-compatible API
Stable implementation (all tests passing)
Reviewed by peers
Documentation
Why Change Streams?
TLDR;
Today, Meteor’s reactivity is based on two approaches:
1. Polling
Polling periodically checks for changes every X ms. It’s used for single Mongo instances or as a fallback when oplog is not available.
2. Oplog
With oplog, we listen to a special MongoDB collection that records all database operations. Meteor then filters those operations and forwards the relevant ones to clients via WebSocket.
For more details, @radekmie have an awesome blog post that mention the oplog issue
What’s the problem?
The oplog registers every operation in the database, even those your app doesn’t care about.
That means:
- Unnecessary load on the server
- More events to process and filter
- Higher memory usage over time
So when you call find inside a publication, Meteor ends up watching all DB operations, then filtering and forwarding only what matches your query.
How Change Streams help
Change Streams create a stream of events based on your query, not the entire database.
So now, when you return a find inside a publication:
- Meteor listens only to operations related to your query
- Less data is transferred
- Resource usage on the server is optimized
In short: more targeted reactivity, less noise.
Improvements
In my tests (I’ll share full benchmarks soon), I didn’t observe significant latency improvements
but I did see a huge reduction in memory usage . ![]()
How to use it
For now, this should be fully transparent from a DX perspective.
You just need to configure your reactivity options in your settings.json:
{
"packages": {
"mongo": {
"reactivity": ["changeStreams", "pooling", "oplog"]
// Meteor will try Change Streams first, then polling,
// and if that doesn't work, fall back to oplog.
}
}
}
I’d love your feedback
This is the first stable implementation, and while it’s already functional, I’d really appreciate feedback on the developer experience (DX) and any edge cases you might think of.
Let me know:
- What you think of this direction
- Any real-world use cases you’d like to see tested
- Any concerns or suggestions before this ships
Thanks a lot! ![]()
