Database queries are often the hidden bottleneck behind application performance issues — dedicated query performance monitoring surfaces exactly which queries need attention. This guide covers setting this up.
Why Application-Level Monitoring Alone Isn't Enough
See How to Monitor Database Performance and Slow Queries for foundational database monitoring — this article covers instrumenting your application code specifically to capture query-level detail correlated with the actual application requests that triggered them.
Instrumenting Query Timing in Application Code
const start = Date.now();
const result = await db.query('SELECT * FROM orders WHERE user_id = $1', [userId]);
const duration = Date.now() - start;
metrics.histogram('db_query_duration_seconds', duration / 1000, { query: 'get_user_orders' });
See How to Set Up Prometheus and Grafana for VPS Monitoring for the metrics infrastructure this feeds into — wrapping database calls with timing instrumentation reveals which specific query patterns are actually slow in production.
Using an ORM's Built-In Query Logging
const sequelize = new Sequelize(dbConfig, {
logging: (sql, timing) => {
if (timing > 100) {
logger.warn('Slow query', { sql, timing });
}
}
});
Many ORMs support query timing callbacks — a lower-effort way to capture slow query detail without manually instrumenting every individual query call site.
Correlating Query Performance with Distributed Traces
See How to Implement Distributed Tracing with Jaeger — database queries as trace spans within a larger request trace reveal exactly how much of a slow request's total time was spent in database operations specifically, versus other processing.
Identifying N+1 Query Problems
Query instrumentation often reveals N+1 query patterns (a loop making individual queries instead of one batched query) — visible as many rapid, similar queries within a single request trace, a common and significant performance anti-pattern this monitoring specifically helps surface.
Tracking Query Performance Trends Over Time
Beyond catching immediately obvious slow queries, track query performance trends — a query that's gradually gotten slower (perhaps due to table growth without corresponding index maintenance) is a pattern only visible through historical trend tracking, not point-in-time observation.
Setting Up Alerts for Slow Query Patterns
See How to Set Up Effective Server Alerting (Without Alert Fatigue) — alert when specific query patterns exceed acceptable duration thresholds, or when overall database query time as a proportion of request time increases significantly.
Building a Query Performance Dashboard
See How to Set Up Grafana Dashboards for Multi-Service Observability — a dedicated view of top slow queries, query volume trends, and database time as a proportion of total request time gives your team ongoing visibility into this often-critical performance dimension.
Using This Data to Prioritize Optimization
See How to Write and Optimize SQL Queries: Indexing Basics for the actual optimization techniques — instrumentation data tells you exactly which queries genuinely warrant optimization effort, rather than optimizing based on guesswork.
Common Errors
Query monitoring shows acceptable individual query times but overall page load is still slow — check for N+1 patterns or excessive total query count per request; many individually-fast queries can still add up to significant cumulative time if genuinely necessary batching/optimization hasn't been applied.
Continue Reading
- How to Monitor Database Performance and Slow Queries
- How to Write and Optimize SQL Queries: Indexing Basics
- How to Implement Distributed Tracing with Jaeger
Browse more articles in Advanced Observability & Incident Management.