Implementing Meteor Live Queries: A Practical Guide to Real‑Time UI Updates
Learn how to set up Meteor’s live query feature to keep your UI in sync with MongoDB. This guide covers prerequisites, subscription setup, error handling, and performance tips, with a concrete example and verification steps.
27 May 2026, 00:59 UTC

Problem & Takeaway
When building a Meteor application, you often need the UI to reflect database changes instantly. Meteor’s live query feature does this automatically by listening to MongoDB’s oplog and pushing updates to subscribed clients. The key takeaway: to use live queries you must run MongoDB in replica‑set mode, publish data with a selector, and handle subscription errors on the client.
Prerequisites
- Node.js 20+ and Meteor 2.11+ installed locally.
- A MongoDB instance configured as a replica set (even a single‑node replica set is sufficient).
- Basic Meteor project structure (
client/,server/,imports/). - Understanding of Meteor’s publish/subscribe model.
Step 1 – Verify MongoDB Replica Set
# On the machine running MongoDB
mongod --replSet rs0 --port 27017 --dbpath /data/db
# In another terminal, connect and initiate the replica set
mongo --port 27017
> rs.initiate()
Use meteor status to confirm the database is reachable. If the status shows a standalone instance, the live query feature will not work.
Step 2 – Define a Reactive Collection
In imports/api/tasks.js:
import { Mongo } from 'meteor/mongo';
export const Tasks = new Mongo.Collection('tasks');
Step 3 – Create a Live Publication
In server/main.js:
import { Meteor } from 'meteor/meteor';
import { Tasks } from '../imports/api/tasks.js';
Meteor.publish('tasksLive', function () {
// Return a cursor that will be tracked live
return Tasks.find({}, { sort: { createdAt: -1 } });
});
This publication uses the default find cursor; Meteor automatically turns it into a live query when the client subscribes.
Step 4 – Subscribe on the Client
In a component (e.g., a Blaze template or React component):
import { Meteor } from 'meteor/meteor';
import { Tasks } from '../imports/api/tasks.js';
Meteor.startup(() => {
Meteor.subscribe('tasksLive', {
onReady() {
console.log('Subscription ready');
},
onStop(error) {
if (error) console.error('Subscription stopped:', error);
}
});
});
For React, you can use useTracker from meteor/react-meteor-data to keep a reactive array.
Step 5 – Render the Live Data
Blaze example:
<template name="tasksList">
<ul>
{{#each tasks}}
<li>{{title}}</li>
{{/each}}
</ul>
</template>
React example:
import { useTracker } from 'meteor/react-meteor-data';
import { Tasks } from '../imports/api/tasks.js';
export const TaskList = () => {
const tasks = useTracker(() => Tasks.find().fetch(), []);
return (
<ul>
{tasks.map(t => (<li key={t._id}>{t.title}</li>))}
</ul>
);
};
Step 6 – Test Real‑Time Updates
- Run
meteor runand open the app in a browser. - Open the Meteor console:
meteor shell. - Insert a document:
Tasks.insert({title: 'New Task', createdAt: new Date()}); - Observe the UI update instantly.
- In Chrome DevTools, disable network and re‑enable to see updates pause and resume.
- Check server logs for
subscription readymessages and any errors.
Expected Checks & Recovery
- Oplog Availability: If updates stop, run
rs.status()to verify the oplog is enabled. Restart MongoDB with--replSetif needed. - Subscription Errors: Handle
onStopcallbacks; common errors includeMongoError: collection not foundorNetwork timeout. Retry logic can be added. - Large Collections: If the UI lags, add a selector to the publication:
return Tasks.find({owner: this.userId});or implement pagination. - Client Memory: Unused subscriptions should be stopped with
subscription.stop()to free memory.
Performance Tips
- Only publish the fields needed:
return Tasks.find({}, { fields: { title: 1, createdAt: 1 } }); - Use
allow/denyrules or Meteor methods to enforce security instead of exposing entire collections. - Monitor network traffic; a burst of change events can saturate bandwidth.
- Consider using
Meteor.deferfor heavy computations on the server to keep the oplog thread responsive.
Limitations & Caveats
Live queries rely on the oplog; they will not work on a standalone MongoDB instance. They are also sensitive to network latency and can generate many change events if the collection is large and unfiltered. Always test under realistic load conditions.
Conclusion
By ensuring MongoDB runs as a replica set, publishing a cursor, and subscribing with proper callbacks, Meteor’s live query feature delivers real‑time UI updates with minimal effort. Use the checks above to validate the setup and recover from common pitfalls.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.