At a glance
Slow-Query Rate % is the share of statements that exceeded long_query_time and were logged as slow, expressed as a percentage of all statements run. It answers “what proportion of my workload is slow?” in a single number. A low percentile-latency reading can still hide a creeping slow-query rate, and vice versa: this card is the volume view of slowness, where the latency percentiles are the severity view. A rising rate is the earliest sign that a missing index, a stale plan, or a saturated buffer pool is starting to bite across real traffic.
| What it tracks | The percentage of executed statements classified as slow over the trailing window. Computed as the change in Slow_queries divided by the change in Questions, both from SHOW GLOBAL STATUS. |
| Data source | SHOW GLOBAL STATUS counters on the MySQL instance: Slow_queries (statements over long_query_time) and Questions (statements run, excluding certain internal commands). The engine takes deltas between samples. |
| Time window | 15m (the rate is computed over a trailing 15-minute window). |
| Alert trigger | > 5%. When the trailing slow-query rate exceeds 5% the card turns red and a Nerve Centre alert is raised. |
| Why it matters | A high slow-query rate means a large fraction of your traffic is running over the slow threshold, holding connections longer, fattening the latency tail, and pushing toward connection pool saturation. It is a leading indicator of a broad performance regression. |
| Reading the value | Read alongside Query Latency p95 and p99. A high rate with a fat tail equals many statements are genuinely slow; a high rate with healthy percentiles usually means long_query_time is set too low. |
| Sentiment key | mysql_slow_query_pct |
| Roles | owner, engineering, operations |
Calculation
The rate is a ratio of two delta counters fromSHOW GLOBAL STATUS, sampled at the start and end of the trailing window.
- Deltas, not absolutes. Both counters are cumulative since server start. Reading them once gives the all-time rate, which is meaningless for “right now”. The engine differences two samples so the number reflects the trailing 15 minutes only.
- The threshold is
long_query_time. A statement is “slow” only relative to the server’slong_query_timesetting (default 10 seconds, often tuned down to 1 or 2 seconds in production). Iflong_query_timeis set very low, almost everything counts as slow and the rate inflates; if it is high, real problems hide. The rate is only as meaningful as the threshold behind it. QuestionsvsQueries. The engine usesQuestions(client-issued statements) as the denominator, notQueries(which also counts statements executed inside stored programs). This keeps the rate aligned with the workload your application actually sends.
Worked example
A platform team runs a MySQL 8.0 primary behind an order-management API withlong_query_time = 1. Snapshot taken on 16 Apr 26 at 17:20 BST during the early-evening order peak.
| Counter | Value at 17:05 | Value at 17:20 | Delta over 15m |
|---|---|---|---|
Slow_queries | 1,204,500 | 1,219,800 | 15,300 |
Questions | 48,210,000 | 48,440,000 | 230,000 |
- 6.65% means roughly one statement in fifteen is running over a second. That is a lot of long-held connections during the evening peak, exactly when connection pool saturation is already tightest.
- They open Top 10 Slowest Queries. Two digests dominate the slow log: an order-history lookup joining
orderstoorder_itemswithout a covering index, and a reporting query an internal dashboard runs on a tight loop. - They confirm against latency. p95 has risen to 240ms and p99 to 1.4s, so the slow rate is real, not an artefact of a too-low
long_query_time. The slowness is genuinely spread across many executions of those two digests.
order_items (order_id, sku, qty) and moving the dashboard query to a read replica. After both ship, the rate drops to 1.1% and the gauge clears. The follow-up is to confirm long_query_time is set sensibly (1 second here is reasonable for an OLTP order API).
Three takeaways:
- Rate and latency answer different questions. Rate is “how much of my traffic is slow”; the percentiles are “how slow is the slow part”. A red rate with healthy percentiles usually means
long_query_timeis too aggressive; a red rate with a fat tail is a real regression. - A high slow rate is a connection-pressure multiplier. Slow statements hold connections, so a rising rate quietly pushes you toward pool exhaustion well before the pool card turns red. Treat the two as linked.
- Two digests usually explain most of it. Slowness is rarely uniform; a handful of digests dominate the slow log. Top 10 Slowest Queries almost always names the fix.
Sibling cards
| Card | Why pair it with Slow-Query Rate | What the combination tells you |
|---|---|---|
| Top 10 Slowest Queries (digest) | Names the digests behind the rate. | Tells you which two or three queries to index or move. |
| Query Latency p95 (ms) | The severity view of the upper band. | High rate plus high p95 equals a real, broad slowdown. |
| Query Latency p99 (ms) | The tail view. | High rate plus a fat p99 confirms the slow part is genuinely slow, not a low threshold. |
| Query Latency p50 (ms) | The median baseline. | A healthy p50 with a high rate means slowness is concentrated, not universal. |
| InnoDB Buffer Pool Hit Rate % | A cold cache turns fast queries slow. | A falling hit rate driving a rising slow rate equals memory pressure, not bad indexes. |
| Connection Pool Saturation % | Slow statements hold connections longer. | Rising slow rate plus rising saturation equals the slowness is consuming pool capacity. |
| Queries per Second (live) | The volume context for the rate. | A high rate at low QPS is less urgent than a high rate at peak QPS. |
| Slow Queries During Checkout Window (5m) | The revenue-path slice of the slow rate. | Confirms whether the slow statements are hitting the checkout path. |
Reconciling against the source
Where to look in MySQL’s own tooling:Why our number may legitimately differ:SHOW GLOBAL STATUSfor the raw counters this card differences:long_query_timeto confirm the threshold the rate is measured against:The slow query log for the actual slow statements (enable withslow_query_log = ONand a sensiblelong_query_time).pt-query-digest(Percona Toolkit) to aggregate the slow log into ranked digests. Managed-service consoles: Amazon RDS / Aurora Performance Insights and the slow-query-log export to CloudWatch Logs give the same statements; RDS publishes aQuestionsmetric you can cross-check.
| Reason | Direction | Why |
|---|---|---|
long_query_time value | Large | The rate is entirely relative to this setting. A 1-second threshold reports far more slow queries than a 10-second threshold on the same workload. Confirm the threshold before comparing. |
| Window boundary | Variable | The card uses a trailing 15-minute delta; a manual SHOW GLOBAL STATUS shows the all-time rate since server start. |
Questions vs Queries | Marginal | The engine uses Questions as the denominator; computing the rate against Queries (which counts stored-program statements) gives a slightly different figure. |
log_queries_not_using_indexes | Higher | If enabled, fast statements that skip an index are also logged as slow, inflating Slow_queries beyond pure time-based slowness. |
| Counter reset | Spike then settle | A FLUSH STATUS or server restart resets the counters; the first delta after a reset can read oddly. |
Known limitations / FAQs
My slow-query rate is red but the latency percentiles look healthy. What is going on? Almost certainlylong_query_time is set too low for your workload. If the threshold is 100ms on an analytics database where 300ms queries are normal and harmless, a large share of statements will be logged as slow even though nothing is actually wrong. Confirm long_query_time matches what “slow” really means for this database before treating the rate as a problem.
Why does the rate use deltas instead of the raw counter?
Slow_queries and Questions are cumulative since server start, so dividing them gives the all-time average, which can be days or weeks old and tells you nothing about now. Differencing two samples over 15 minutes gives the current rate, which is what you actually need during an incident.
The card reads zero. Is slow-query tracking even on?
The counters increment regardless of whether the slow query log is written, so the rate works even with slow_query_log = OFF. A genuine zero means no statements crossed long_query_time in the window, which is good. If you also want to see the offending statements, enable the slow query log; the rate and the log are independent.
Does log_queries_not_using_indexes affect this number?
Yes. With that option on, statements that do not use an index are counted as slow even if they were fast, which inflates Slow_queries and the rate. That can be useful for catching missing indexes, but be aware the rate then mixes “slow by time” with “slow by plan”. Disable it if you want the rate to mean purely time-based slowness.
Can I change the 5% alert threshold?
Yes, per profile in the Sensitivity tab. A reporting database may tolerate a higher rate; a latency-sensitive checkout database may want it tighter, for example 2%. Set it relative to your normal busy-hour rate so it only fires on genuine regressions.
Is a high slow-query rate at low traffic something to worry about?
Less than at peak, but not nothing. At low QPS, a 10% slow rate might be a handful of statements and easy to ignore; the same 10% at peak is thousands of long-held connections. Read the rate next to Queries per Second to judge urgency, and remember that the same regression will hurt far more once traffic ramps.
The rate jumped right after a deploy. Coincidence?
Usually not. The two most common post-deploy causes are a new query that lacks an index and an ORM change that turned one efficient query into an N+1 pattern. Open Top 10 Slowest Queries and look for a digest that did not exist before the deploy; that is your regression.