MongoDB alert rules for Prometheus: 8 rules with runbooks
8 ready-to-use MongoDB alert rules in PromQL, each with severity, duration and runbook steps. Metrics from mongodb_exporter. Download as a Prometheus rules file or import into Nightingale.
Last reviewed
MongoDB alert rules for an instance that has crashed or just restarted, connections approaching the limit, high average operation latency, assertion errors, cursor timeouts, page faults and replica-set lag. They use mongodb_exporter metric names.
At a glance
- 8 rules, each with a PromQL condition, a severity, a
forduration and runbook steps - Metrics from: mongodb_exporter
- Download:
mongodb.yml, a standard Prometheus rules file (groups:format), checked withpromtool check rules - Thresholds are starting points. Adjust them to your environment before enabling the rules.
Rule list
| Rule | Severity | For |
|---|---|---|
| MongoDB average operation latency exceeds 250ms - exporter | Warning | 10m |
| Mongo connection number has exceeded 80% - exporter | Warning | 2m |
| Mongo has encountered an Assert error - exporter | Info | 30m |
| Mongo has encountered cursor timeout - exporter | Warning | 30m |
| Mongo has encountered page fault interrupt - exporter | Warning | 30m |
| Mongo has just restarted, please pay attention - exporter | Info | — |
| Mongo instance has crashed - exporter | Critical | — |
| Mongo replica set master-slave delay exceeds 30 seconds - exporter | Critical | 1m |
Prometheus exporter (8)
MongoDB average operation latency exceeds 250ms - exporter
Warning · 10m · Trigger:
rate(mongodb_mongod_op_latencies_latency_total[5m]) / rate(mongodb_mongod_op_latencies_ops_total[5m]) > 250000
Runbook:
- Run db.currentOp({"secs_running":{$gt:5}}) to find long-running operations and db.killOp(opid) to stop the bleeding if needed;
- Enable the profiler to find slow queries: db.setProfilingLevel(1,100), then db.system.profile.find().sort({millis:-1}).limit(10);
- Run explain("executionStats") on the slow queries to see whether they do a COLLSCAN and add indexes;
- Check whether a bulk write or an index rebuild is saturating disk IO.
Mongo connection number has exceeded 80% - exporter
Warning · 2m · Trigger:
avg by (instance) (mongodb_connections{state="current"}) / (avg by (instance) (mongodb_connections{state="current"}) + avg by (instance) (mongodb_connections{state="available"})) * 100 > 80
Runbook:
- Run db.serverStatus().connections to see the real current and available levels;
- Run db.currentOp(true) and group by client to find the application with an abnormal connection count;
- Tell business growth apart from a driver connection pool leak (maxPoolSize set too high, or the MongoClient is not reused);
- As an emergency measure raise net.maxIncomingConnections on mongod, and confirm the system ulimit -n is high enough.
Mongo has encountered an Assert error - exporter
Info · 30m · Trigger:
rate(mongodb_asserts_total{type=~"regular|message"}[5m]) > 0
Runbook:
- Run db.adminCommand({getLog:"global"}) to see the context of the asserts in the log;
- Run db.serverStatus().asserts to see whether the regular or message counter is growing;
- Regular asserts usually point to the storage layer — check disk health and data file integrity; message asserts usually mean a protocol or driver mismatch, so verify the driver version;
- Check whether it lines up with a recent upgrade or schema change.
Mongo has encountered cursor timeout - exporter
Warning · 30m · Trigger:
rate(mongodb_mongod_metrics_cursor_timed_out_total[5m]) > 0
Runbook:
- Run db.serverStatus().metrics.cursor and watch timedOut against open.total;
- On the application side, confirm cursors are close()d after use and that a single batch does not take too long;
- For long traversals use noCursorTimeout and manage the lifecycle yourself, or lower batchSize to consume faster;
- Check whether a slow query is holding a cursor past cursorTimeoutMillis (10 minutes by default).
Mongo has encountered page fault interrupt - exporter
Warning · 30m · Trigger:
rate(mongodb_extra_info_page_faults_total[5m]) > 0
Runbook:
- Run db.serverStatus().wiredTiger.cache and compare "bytes currently in the cache" against the configured limit;
- Compare db.stats() and index sizes against physical memory to judge whether the working set exceeds RAM;
- Start by dropping unused indexes and archiving cold data to shrink the working set;
- Confirm the host is not swapping, and add memory or shard if necessary.
Mongo has just restarted, please pay attention - exporter
Info · — · Trigger:
mongodb_instance_uptime_seconds < 60
Runbook:
- Read the tail of the mongod log to tell a crash, an OOM kill and a manual restart apart;
- If it was an OOM, compare wiredTigerCacheSizeGB against host memory and lower it;
- For a replica set, run rs.status() to confirm a new primary was elected automatically and applications reconnected;
- For an unplanned restart, check whether systemd or the container orchestrator is repeatedly restarting it.
Mongo instance has crashed - exporter
Critical · — · Trigger:
mongodb_up == 0
Runbook:
- Log in to the host and run systemctl status mongod or docker ps to confirm the process is alive;
- If it is alive, connect by hand with mongosh to tell a hung instance apart from a network or authentication problem;
- If it is not running, read the tail of the log to identify the cause (OOM, full disk, corrupted data files) before starting it — do not blindly restart;
- For a replica set, run rs.status() immediately to confirm failover completed and that the application has taken this node out of rotation.
Mongo replica set master-slave delay exceeds 30 seconds - exporter
Critical · 1m · Trigger:
(max by (rs_nm) (mongodb_rs_members_optimeDate) - min by (rs_nm) (mongodb_rs_members_optimeDate)) / 1000 > 30
Runbook:
- Run rs.status() on the primary and compare optimeDate and lastHeartbeat across members to find the lagging one;
- On the lagging node, check the mongod log for oplog fetch errors or disk IO bottlenecks;
- On the primary, run db.currentOp() to check whether a bulk write is flooding the oplog faster than the secondary can apply;
- If it falls behind the oplog window the secondary needs a fresh initial sync — move read traffic away first.
How to use these rules
- With Prometheus or vmalert: download
mongodb.yml, add it torule_files(or-rulefor vmalert), check the metric names against your exporter version, and tune thresholds. Severity is set as aseveritylabel (critical / warning / info), andrunbook_urlpoints back to this page, or to the rule's own page where it has one. - With Nightingale: the same rules ship in the MongoDB integration template. Open the integration center, import the rules into a business group, and enable them one by one. Nightingale keeps the runbook with each alert and can evaluate the rules against Prometheus, VictoriaMetrics and other data sources.
Sources and license
The runbook steps and the remaining rules come from Nightingale's integration templates (MongoDB, Apache-2.0). Corrections are welcome as pull requests there.
Related
- Monitor MongoDB with Nightingale: collector config, dashboards and metric reference
- Write a metric rule in Nightingale
- All alert rules