MongoDB change streams.
Basic
with db.users.watch() as stream:
for change in stream:
print(change)
Watches for inserts, updates, deletes.
Operation types
insertupdatereplacedeleteinvalidate(collection dropped)
Filter
pipeline = [{"$match": {"operationType": "insert"}}]
with db.users.watch(pipeline) as stream:
for c in stream:
process(c)
Watch DB or cluster
db.watch([...]) # entire db
client.watch([...]) # entire cluster
Resume
token = None
while True:
try:
with db.users.watch(resume_after=token) as stream:
for change in stream:
process(change)
token = change["_id"]
except Exception:
time.sleep(5)
Resume from last token after disconnect.
Persist token
Save token to DB / Redis after each batch. On restart, resume from saved.
Full document
stream = db.users.watch(full_document="updateLookup")
For updates: include current full doc (extra query).
Pre/post images (newer Mongo)
db.runCommand({
collMod: "users",
changeStreamPreAndPostImages: { enabled: true }
})
stream = db.users.watch(
full_document="required",
full_document_before_change="required",
)
Useful for “what changed” diffs.
Use cases
- CDC to Elasticsearch / data warehouse.
- Cache invalidation.
- Event-driven workflows.
- Audit log.
- Sync to other systems.
Node.js
const stream = collection.watch([
{ $match: { operationType: "insert" } }
]);
for await (const change of stream) {
process(change);
}
Performance
- Each change stream = one cursor on primary’s oplog.
- Many parallel streams = oplog pressure.
- Filter early via pipeline.
Resume token expiry
If gone too long → token might be unresumable. Reasons:
- Oplog too small.
- Token from another node post-failover.
Mitigations:
- Big oplog.
- Use
start_after(more lenient) instead ofresume_after.
Common mistakes
- No resume token persistence → lose changes on restart.
- Heavy work in handler → can’t keep up.
- Single change stream as single point of failure.
- Forgetting that delete event has only
_id, not full doc.
Read this next
If you want my CDC pipeline, it’s at rajpoot.dev .
Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .