
Database monitoring is most effective when it answers one question: “What changed that requires action?” Teams often start by collecting lots of metrics, then drown in noisy alerts that don’t map to customer impact. A better approach is to define a small set of actionable alert categories and implement them with read-only checks (SQL/NoSQL queries, metadata queries, and lightweight health checks) that reflect real risk.
This guide breaks down what to monitor in SQL and NoSQL databases, which alerts matter most, and how to implement low-noise patterns that scale across PostgreSQL, MySQL, and MongoDB.
Why “what to alert on” matters more than “what to collect”
Modern stacks can export hundreds of metrics. But the strongest database monitoring setups share a few traits:
- Customer-impact focus: alerts correlate with outages, data loss, or degraded user experience.
- Clear owners: every alert has a responder and a documented playbook.
- Low noise: thresholds and windows are tuned to avoid flapping and false positives.
- Defense in depth: combine infrastructure signals (CPU, storage) with data signals (backlog, missing rows, stalled pipelines).
Instead of trying to alert on everything, start with a “minimal viable alert set” and expand only when it prevents real incidents.
The 6 alert categories that cover most production incidents
Use these categories as a checklist. They apply to both SQL and NoSQL systems, even if the implementation differs.
| Category | What it catches | Example signal | Best response |
|---|---|---|---|
| Availability & connectivity | Outages, DNS/VPC issues, credential failures | Cannot connect / auth failures spike | Failover, restore access, rotate creds |
| Performance & saturation | Slow queries, lock contention, resource exhaustion | P95 query latency > SLO for 10 min | Index/tune queries, reduce load, scale |
| Capacity & storage risk | Disk full, table/index growth, log bloat | Free storage < 15% | Clean up, archive, increase storage |
| Replication & durability | Replica lag, failed backups, WAL issues | Replica lag > 60s | Fix replication, investigate network/IO |
| Data integrity & correctness | Missing rows, stuck jobs, broken constraints | Orders in “pending” > 30 min | Repair pipeline, reprocess, backfill |
| Security & anomaly signals | Suspicious access, privilege drift | Failed logins spike, new superuser | Block, rotate keys, audit changes |
Start with SLIs: define what “bad” means for your database
Alerting works best when derived from service-level indicators (SLIs). For database monitoring, common SLIs include:
- Latency: P95/P99 query latency for critical endpoints (checkout, login, search).
- Error rate: timeouts, deadlocks, duplicate key errors, write conflicts.
- Freshness: delay between source events and analytics tables, or CDC backlog.
- Durability: backup success, restore verification, replica lag.
Turn SLIs into alerts by specifying: threshold, evaluation window, and severity. Example: “P95 checkout query latency > 250ms for 10 minutes” (page) versus “> 250ms for 2 minutes” (warn).
Query-based alerts: practical SQL patterns (PostgreSQL/MySQL)
Queries are a direct way to encode business risk. They’re also portable: the same idea works across environments and can be executed read-only. Below are patterns that typically produce high-signal alerts.
1) Stuck workflow detection (business-impact)
If orders, invoices, or messages can get stuck, alert on age in a “non-terminal” state.
-- PostgreSQL: orders stuck in pending > 30 minutes
SELECT count(*) AS stuck_orders
FROM orders
WHERE status = 'pending'
AND created_at < now() - interval '30 minutes';
Alert rule: notify when stuck_orders > 0. Consider adding a minimum count (e.g., > 5) to reduce noise during deploys.
2) Backlog or queue growth (leading indicator)
Backlogs often show up before customers complain.
-- MySQL: backlog of unprocessed jobs
SELECT COUNT(*) AS backlog
FROM jobs
WHERE status = 'queued'
AND created_at < NOW() - INTERVAL 10 MINUTE;
Alert rule: warn when backlog exceeds a baseline; page when it exceeds a higher threshold or grows rapidly.
3) Data freshness for analytics tables (trust and correctness)
Analytics incidents are often silent. Alert when a table stops updating.
-- PostgreSQL: last successful ingestion timestamp
SELECT EXTRACT(EPOCH FROM (now() - max(loaded_at)))::int AS seconds_since_load
FROM fact_events;
Alert rule: notify if seconds_since_load > 900 (15 minutes), tuned to your expected cadence.
4) Lock contention and deadlocks (performance + availability)
In relational systems, locks can cascade into timeouts.
-- PostgreSQL: count blocked queries older than 30 seconds
SELECT count(*) AS blocked
FROM pg_stat_activity
WHERE wait_event_type = 'Lock'
AND now() - query_start > interval '30 seconds';
Alert rule: page when blocked queries persist for multiple intervals (e.g., 3 checks in a row).
NoSQL patterns: MongoDB alerts that stay actionable
MongoDB monitoring often focuses on replication health, connection saturation, and slow queries—but query-level checks are also useful for data correctness and workflow safety.
1) Stale documents or state drift
Similar to SQL “stuck workflow,” but expressed as a document query.
// MongoDB: count documents stuck in processing for > 30 minutes
db.tasks.countDocuments({
status: "processing",
updatedAt: { $lt: new Date(Date.now() - 30 * 60 * 1000) }
});
2) Outlier detection with percentiles (when supported by your pipeline)
If you store request durations or job runtimes in MongoDB, you can alert on tail latency or a sudden shift in distribution. Even a simple “max in last N minutes” can be a strong early warning.
// MongoDB: max duration in last 10 minutes
db.jobRuns.aggregate([
{ $match: { startedAt: { $gte: new Date(Date.now() - 10 * 60 * 1000) } } },
{ $group: { _id: null, maxMs: { $max: "$durationMs" } } }
]);
Reducing alert fatigue: 8 rules that keep database monitoring quiet
- Alert on symptoms, not every metric: disk at 70% is information; disk at 90% with rapid growth is an alert.
- Use windows and consecutive failures: require 2–3 failing checks to avoid flapping.
- Separate warn vs page: paging should be rare and tied to impact.
- Prefer rate-of-change: “backlog growing 20% per interval” is often more meaningful than an absolute number.
- Set per-environment thresholds: staging noise should not train the team to ignore alerts.
- Deduplicate by root cause: one incident shouldn’t trigger 12 different pages.
- Add context to notifications: include top offenders (e.g., top slow queries) and a runbook link.
- Retire alerts aggressively: if an alert never finds real issues, remove or redesign it.
Security considerations for query-driven monitoring
Database monitoring is a privileged activity. Treat alert queries as production access and implement basic controls:
- Read-only credentials: use a dedicated monitoring user limited to required schemas/collections.
- Encrypted connections: enforce TLS; validate certificates where possible.
- Network boundaries: restrict access by IP/VPC, and avoid exposing databases publicly.
- Least-knowledge queries: select counts and timestamps instead of sensitive fields.
- Auditing: log access for monitoring users and review periodically.
Rule of thumb: if an alert can be computed with counts and max timestamps, don’t pull full rows.
A lightweight alert design template (copy/paste)
When you add a new alert, document it in a consistent format so it stays maintainable:
- Name: “Orders pending > 30 minutes”
- Type: Data correctness / workflow
- Query: link to SQL/NoSQL check
- Threshold: > 0 for 3 consecutive checks
- Severity: page (business impact) or warn
- Owner: team/on-call rotation
- Runbook: steps to investigate, dashboards to open, common fixes
- Expected noise: “none during normal operation” or “may spike during backfills”
Putting it together: a minimal viable database monitoring alert set
If you’re building from scratch, start with these 10 alerts. They cover the majority of urgent incidents without overwhelming responders:
- Cannot connect (availability)
- Replica lag (durability)
- Backup failed (durability)
- Free storage low (capacity)
- CPU/IO saturation sustained (performance)
- P95 latency for critical query group (performance)
- Deadlocks/lock waits sustained (performance)
- Workflow stuck (data correctness)
- Data freshness stale (analytics correctness)
- Auth failures spike (security signal)
Once these are stable, add alerts for your specific domain (fraud thresholds, inventory drift, billing anomalies), but only after you’ve defined the responder action.
Conclusion
Strong database monitoring isn’t about collecting every metric—it’s about choosing a small set of alerts that reflect customer impact, implementing them securely with read-only checks, and tuning them to stay quiet until action is needed. Start with availability, performance, capacity, durability, correctness, and security signals, then iterate based on real incidents.
If you prefer running these query checks from a mobile workflow, tools like Query Alert can turn SQL/NoSQL queries into scheduled notifications while keeping access read-only and encrypted.