
Traditional MongoDB monitoring often starts with infrastructure metrics (CPU, memory, disk I/O) and stops there. Those signals matter, but they rarely answer the question your team actually cares about: is the data behaving the way the product depends on? That’s where query-based alerting shines.
When you monitor MongoDB with query alerts, you turn your database into a source of actionable signals: backlog growth, missing data, suspicious activity, broken ETL, stale documents, failing jobs, or business-critical thresholds. This article walks through practical alert patterns, example queries, and tactics to keep alerts accurate, secure, and low-noise.
What “query alerts” mean for MongoDB monitoring
A query alert is a scheduled MongoDB query (often an aggregation pipeline) that returns a small result used to decide whether to notify someone. The goal is simple:
- Detect a meaningful condition (threshold, anomaly, missing event).
- Explain what is wrong in one glance (include key fields).
- Guide a next step (link to a runbook or remediation action).
This approach complements metrics-based monitoring instead of replacing it. Metrics tell you something is hot; query alerts tell you what is broken for users.
Design principles for low-noise MongoDB alerts
Most alert fatigue comes from rules that are easy to trigger and hard to interpret. Use these principles to keep your alerts trustworthy:
- Alert on outcomes, not raw activity. For example, “orders stuck in pending for 30 minutes” is better than “orders created per minute dropped.”
- Prefer windows and rates over single points. Look at the last 5–15 minutes to avoid spikes.
- Return small, human-readable results. Include counts and 2–5 example IDs for triage.
- Make thresholds environment-specific. Staging and production rarely share the same baseline.
- Index for your alert queries. If alerts cause load, they’ll be turned off during the exact incident you need them.
Core alert patterns (with examples)
The best way to monitor MongoDB with query alerts is to start from a short list of repeatable patterns. The table below maps common needs to MongoDB query shapes.
| Monitoring goal | Query pattern | Typical output |
|---|---|---|
| Backlog detection | Count documents in a state older than a time threshold | count + sample IDs |
| Freshness / SLA | Find newest/oldest timestamp; compare to “now” | latest timestamp + lag minutes |
| Error rate | Group errors by type over a window | counts by errorCode |
| Data integrity | Find missing fields or invalid states | count + examples |
| Security signals | Detect unusual spikes, failed logins, risky changes | count + top sources |
1) Backlog alert: “stuck” documents
Queues and workflows often live in MongoDB (e.g., status: 'pending', status: 'processing'). A common failure mode is that work stops progressing.
// Documents pending for more than 30 minutes
// Assumes an index on { status: 1, createdAt: 1 }
[
{ $match: {
status: 'pending',
createdAt: { $lt: new Date(Date.now() - 30 * 60 * 1000) }
}},
{ $facet: {
summary: [ { $count: 'stuckCount' } ],
examples: [ { $project: { _id: 1, createdAt: 1 } }, { $limit: 5 } ]
}}
]
Alert rule idea: notify if stuckCount > 0, or if it exceeds a baseline (e.g., > 50) depending on traffic.
2) Data freshness alert: “pipeline stopped”
If your app depends on data being updated regularly (ingestion, sync jobs, analytics snapshots), measure freshness directly.
// Last successful import time
// Assumes documents include: { jobName, status, finishedAt }
[
{ $match: { jobName: 'daily_import', status: 'success' } },
{ $sort: { finishedAt: -1 } },
{ $limit: 1 },
{ $project: {
_id: 0,
finishedAt: 1,
minutesSince: {
$divide: [ { $subtract: [ '$$NOW', '$finishedAt' ] }, 1000 * 60 ]
}
}}
]
Alert rule idea: notify if minutesSince > 90 (or your SLA). This yields a crisp, non-ambiguous incident: data is stale.
3) Error-rate alert: group and rank
Instead of alerting on every error document, group errors by type and alert when a type spikes. This reduces noise while improving diagnosis.
// Error counts by errorCode over the last 10 minutes
// Assumes an index on { createdAt: 1, errorCode: 1 }
[
{ $match: { createdAt: { $gte: new Date(Date.now() - 10 * 60 * 1000) } } },
{ $match: { level: 'error' } },
{ $group: { _id: '$errorCode', count: { $sum: 1 } } },
{ $sort: { count: -1 } },
{ $limit: 5 }
]
Alert rule idea: notify if any count exceeds a threshold (static or baseline-based). Include the top 3 error codes in the notification so the on-call engineer doesn’t have to log in to learn what’s happening.
4) Data integrity alert: missing or invalid fields
Schema drift and partial writes are silent killers in document databases. Create alerts for “should never happen” cases.
// Orders missing a required field
// Assumes an index on { createdAt: 1 }
[
{ $match: {
createdAt: { $gte: new Date(Date.now() - 24 * 60 * 60 * 1000) },
$or: [
{ customerId: { $exists: false } },
{ totalAmount: { $exists: false } },
{ currency: { $nin: [ 'USD', 'EUR', 'GBP' ] } }
]
}},
{ $facet: {
summary: [ { $count: 'badCount' } ],
examples: [ { $project: { _id: 1, customerId: 1, totalAmount: 1, currency: 1 } }, { $limit: 5 } ]
}}
]
Alert rule idea: notify if badCount > 0. Integrity alerts should be rare; when they fire, they deserve attention.
5) Security signal alert: failed authentication spikes
If you store auth events (or API audit events) in MongoDB, you can detect suspicious spikes without needing a full SIEM pipeline on day one.
// Failed login attempts per IP over the last 15 minutes
// Assumes fields: { createdAt, eventType, ip }
[
{ $match: {
createdAt: { $gte: new Date(Date.now() - 15 * 60 * 1000) },
eventType: 'login_failed'
}},
{ $group: { _id: '$ip', count: { $sum: 1 } } },
{ $match: { count: { $gte: 20 } } },
{ $sort: { count: -1 } },
{ $limit: 10 }
]
Alert rule idea: notify when any IP crosses the threshold. Add a runbook step like “block IP at WAF” or “require CAPTCHA.”
Scheduling: pick intervals that match the failure mode
How often you run alert queries matters as much as the query itself:
- Fast feedback (1–5 minutes): backlogs, spikes, job failures, ingestion stoppage.
- Medium (10–30 minutes): freshness SLAs, drifting error rates, slow-moving incidents.
- Slow (daily): integrity audits, unusual growth checks, storage planning signals.
Tip: If an incident can cause rapid damage (fraud, runaway queue, deletion), don’t schedule the alert hourly. Match the schedule to the cost of delay.
Performance and correctness: indexes, time windows, and sampling
Query alerts are only helpful if they’re safe to run in production. Use these tactics to keep checks efficient:
- Always filter by time when possible. Most operational alerts should look at “last N minutes/hours.”
- Index your match stage. If you match on
statusandcreatedAt, build{ status: 1, createdAt: 1 }. - Project only what you need. Reduce payload with
$projectbefore returning examples. - Use sampling for large sets. If you only need examples, return a handful via
$limit(or$sampleif appropriate). - Prefer counts over full document returns. Alerts should be small and fast.
Security: monitor with least privilege
To monitor MongoDB with query alerts safely:
- Use a read-only user scoped to the minimum databases/collections required.
- Enforce TLS for connections, especially from mobile or remote networks.
- Avoid sensitive fields in alert output (PII, secrets). Return IDs and counts, not full documents.
- Log access to monitoring credentials and rotate them regularly.
Make alerts actionable: include context and a runbook
An alert that says “something changed” is not enough. Design your output to answer: what happened, where, and what should I do next?
A practical alert message template:
- Signal: “Orders stuck in pending > 30 min”
- Magnitude: “stuckCount=42”
- Examples: “orderIds: 661f…, 6620…, 6621…”
- Next step: “Runbook: check worker queue, recent deploy, and MongoDB index health”
Common pitfalls (and how to avoid them)
- Alerting on raw counts without context: use rates or compare against a baseline window.
- Unbounded queries: add time windows and correct indexes.
- Duplicative alerts: add deduplication keys (e.g., same errorCode) and cool-down periods.
- Too many “integrity” checks at high frequency: run heavy audits daily, not every minute.
Putting it together: a simple alert checklist
- Pick one user-impacting condition (stuck, stale, failing, suspicious).
- Write a query that returns count + examples in under a second.
- Add the right compound index for the
$matchstage. - Schedule it at an interval matched to incident cost.
- Define thresholds and a runbook link.
- Review noisy alerts weekly and refine.
Once you have 5–10 well-designed checks, you’ll have a monitoring layer that reflects real operational risk and business health—not just server saturation.
Gentle note: if you prefer running these checks from an iOS workflow with push/email notifications and read-only, encrypted connections, tools like Query Alert are built around this query-to-alert model.