SQL Planner — User Guide

SQL Planner User Guide — for DBAs & IT Administrators

About Wait Analysis Dashboard

SQL Planner shows you what your SQL Servers are spending their time waiting on — and which queries are responsible — so you can find and fix performance problems quickly.

Every time SQL Server runs a query, parts of that work involve waiting: waiting for a disk read, waiting for a lock to be released, waiting for memory, waiting to write to the transaction log. SQL Planner samples these waits continuously, adds them up, and attributes them to the exact SQL statement that caused them.

The practical result: instead of guessing from "CPU looks high," you can answer the real question directly — "which statements are slow, and what are they waiting for?" That is the fastest route to a fix, because the wait type usually points straight at the cause (a missing index, blocking, slow storage, and so on).

The one-line mental model: long bars = lots of waiting = where to look. The color of the bar tells you what kind of waiting. The grid below tells you which query.

The pages at a glance

Wait-Time Analysis

The main dashboard. See waits over time, by category, drill into any time period, and find the top waiting queries.

Query Detail

Deep dive on a single statement: full text, tuning findings, suggested indexes, execution stats, and the execution plan.

Wait Alerts

Automatic alerts when a server's waits are unusually high compared to its own normal weekly pattern.

Collector Health

Confirms data is actually being collected, so you can trust that "no alerts" really means "all healthy."

Wait-Time Analysis (the main dashboard)

This is where you spend most of your time. The left panel has two controls; the right side shows a chart and a table.

1. Choose a server

The Server dropdown selects which SQL Server you're looking at. There is also a special All Servers (overview) option at the top.

  • A specific server — the chart breaks waits down by category (Disk I/O, Locking, etc.) for that one server.
  • All Servers (overview) — the chart breaks waits down by server, so each colored segment is a whole server. Use this to spot, across your whole estate, which server is the busiest. Click that server's segment to jump straight into its detailed view.

2. Choose a timeframe

The Timeframe dropdown ranges from Last 1 Hour up to Last 90 Days. SQL Planner automatically picks the right level of detail: recent timeframes show fine-grained data (down to 5-minute bars), while longer ones show daily bars for a clean trend.

Tip: start wide (Last 7 Days) to see the trend, then narrow (Last 24 Hours, then drill in) to zoom in on a specific spike.

Reading the chart

The chart is a stacked bar chart. Each bar is a slice of time (an hour, a day, etc.). The total height is the total wait time in that slice; the colored segments show how that total splits up.

Colors

In single-server view, each color is a wait category, and colors are fixed — Disk I/O is always the same blue, Locking is always red — so you learn to read the chart at a glance:

Disk I/O   Transaction Log   Locking / Blocking   Memory   CPU   Buffer Latch   Network / Client   External / OS

Units

The vertical axis label tells you the unit — Wait Time (s), (min), or (hr). SQL Planner picks the most readable unit automatically based on how large the values are, so you never see an unreadable number like "2,460,000 ms."

Filtering categories (single-server view)

Click any category name in the legend below the chart to hide it. The bars, the grid, and the percentages all update to exclude it. This is useful when one huge category (often Disk I/O) hides everything else — hide it, and the smaller waits become readable. Click the name again to bring it back.

Drilling down

The chart is interactive. Click a bar to zoom into that time period at a finer resolution:

1
Click a day bar → see that day broken into hours.
2
Click an hour bar → see that hour broken into 5-minute intervals.
3
Use ← Reset drill-down (top-left of the chart) to return to the full timeframe.

The breadcrumb above the chart always shows the exact window you're viewing, in UTC. As you drill, the statements grid below updates to match — so you're always seeing the queries that were waiting in that specific window.

The "Top 50 Waiting SQL Statements" grid

Below the chart is the list of statements that waited the most in the current view, highest first. Columns:

ColumnWhat it tells you
Server(Overview only) which server the statement ran on.
SQL StatementThe statement text (click it to open Query Detail). The grey line beneath is its fingerprint.
CategoryThe kind of wait this row represents (Disk I/O, Locking, etc.).
Wait TypeThe exact underlying wait (e.g. PAGEIOLATCH_SH).
Total Wait TimeHow much time was spent waiting, auto-scaled (ms / s / min / hr).
PercentageThis row's share of the total wait in the current view.
ExecutionsHow many times the statement ran in the window.
FindingsTuning hints detected from the execution plan (see badges below).

Finding badges

If SQL Planner spots a tuning opportunity in the statement's plan, it shows a badge:

Missing index a useful index doesn't exist   Scan reading a whole table/index   Implicit conversion a datatype mismatch slowing things   Key lookup extra lookups that an index could cover   tempdb spill ran out of memory, spilled to disk

How to use the grid: the top row is your biggest opportunity. If it carries a Missing index badge, that's often a quick win — click the statement to get the suggested index.

Query Detail

Clicking a statement opens its detail page, which gives you everything needed to act:

  • Full statement text — the complete SQL, not the truncated grid version.
  • Findings — the same badges, expanded with specifics (e.g. the missing index's estimated impact).
  • Suggested index — ready-to-review CREATE INDEX DDL when a missing index was detected.
  • Execution statistics — execution count, CPU, reads, and related metrics.
  • Execution plan — download the .sqlplan file to open in SQL Server Management Studio.
Always review before applying. Suggested indexes are a strong starting point, not a guarantee. Check that a similar index doesn't already exist, consider the write overhead, and test in a non-production environment first.

Wait Alerts

SQL Planner learns each server's normal weekly pattern — what its waits typically look like at, say, 9am on a Tuesday versus 3am on a Sunday — and raises an alert when an hour is unusually high compared to that normal. This is far more useful than a fixed threshold, because "normal" is different for a busy weekday morning than a quiet weekend night.

Reading an alert

ColumnMeaning
SeverityCritical = far outside normal; Warning = notably outside normal.
Server / CategoryWhich server and which kind of wait spiked.
When (UTC)The hour that triggered, plus its day/time-of-week.
Observed vs NormalWhat actually happened vs. the learned baseline for that hour.
DeviationHow far outside normal — e.g. 4.3σ means "4.3 standard deviations above normal."
StatusOpen, Acknowledged, or Resolved.

The triage workflow

1
Acknowledge — "I've seen this and I'm looking into it." This records who took ownership and stops two people chasing the same alert.
2
Investigate — go to Wait-Time Analysis, pick that server, set the timeframe around the alert's hour, and drill in to see which queries drove the spike.
3
Resolve — once handled (fixed, or confirmed as a known one-off like a backup window), mark it Resolved to clear it from the active list.
The default "Open only" filter keeps this page focused on what still needs attention. A quiet page is a good sign — but only if Collector Health is green (see below).

Collector Health

This page answers a critical question: is data actually being collected? Without it, an empty alert list is ambiguous — it could mean "everything's healthy" or "the collector died and we're blind." This page removes that doubt.

Per-server status

Each server shows a status based on how recently it sent data:

StatusMeaningAction
HealthyFresh data arriving (within the last few minutes).None.
StaleNo data for several minutes — collector may be lagging, or the server is idle.Check the collector task; verify whether the server is genuinely idle.
DownNo data for over 10 minutes, or never.The collector for that server likely stopped — investigate.

Other columns: Coverage (of the last 60 minutes, how many actually have data — a gap detector), Query insight freshness, Lease (whether it's collecting right now), and Last error.

Background jobs

The lower panel shows the freshness of the scheduled maintenance jobs — Hourly rollup, Baseline build, and Alert evaluator. If any of these reads "days ago" or "never," its scheduled task isn't running, and the features that depend on it (long-range charts, alerts) will be stale. This is the page that tells you to go check your scheduled tasks.

The page auto-refreshes every 60 seconds. Glance at it after any maintenance to confirm everything came back healthy.

Common tasks (quick playbook)

"A server feels slow right now"

  1. Open Wait-Time Analysis, pick the server, set timeframe to Last 1 Hour.
  2. Look at the tallest recent bar and its dominant color — that's the bottleneck category.
  3. Click that bar to drill into 5-minute detail; check the grid for the top waiting statement.
  4. Click the statement → review findings and suggested index on Query Detail.

"I received a Critical alert"

  1. Open Wait Alerts, find the alert, click Acknowledge.
  2. Note its server, category, and hour. Go to Wait-Time Analysis, pick that server.
  3. Set the timeframe to cover that hour and drill in; identify the driving query.
  4. Fix or rule out, then return and Resolve the alert.

"The dashboard shows no data"

  1. Open Collector Health. Is the server Down? The collector isn't sending data.
  2. Check the Background jobs panel — is the hourly rollup current? If not, long-range views will be empty.
  3. Confirm the scheduled tasks (collector, and the maintenance job) are running.

"Which server in my estate is worst?"

  1. Open Wait-Time Analysis, choose All Servers (overview), set a wide timeframe.
  2. The tallest bars and largest colored segments are your busiest servers.
  3. Click a server's segment to jump into its detailed view.

Wait categories — what they usually mean

CategoryTypically points to…
Disk I/OSlow storage, missing indexes causing large reads, or memory pressure forcing disk reads.
Transaction LogHeavy writes, slow log storage, or frequent small transactions.
Locking / BlockingOne query blocking others — contention, long transactions, or lock escalation.
MemoryMemory grants waiting — large sorts/hashes, or overall memory pressure.
CPUCPU pressure or thread starvation — too much work for available cores.
Buffer LatchIn-memory page contention — often hot pages or tempdb contention.
Network / ClientThe application/client is slow to consume results — usually app-side, often benign.
External / OSTime spent outside SQL Server (OS calls, extended procedures).
These are starting points, not diagnoses. The category tells you where to look; the statement and its plan tell you why.

Glossary

TermPlain meaning
WaitTime SQL Server spends not running a query because it's waiting for something (disk, lock, memory…).
Wait typeThe specific thing being waited on (e.g. PAGEIOLATCH_SH = waiting for a data page to be read from disk).
CategoryA friendly grouping of related wait types (Disk I/O, Locking/Blocking, etc.).
Baseline / "normal"What a server's waits typically look like at a given hour of the week, learned from recent history.
Sigma (σ)How far outside normal something is. 3σ ≈ unusual; 6σ ≈ very unusual.
Drill-downClicking a bar to zoom into a smaller, more detailed time window.
CoverageOf the last hour, how many minutes actually have collected data (a gap check).
UTCAll times in SQL Planner are shown in UTC for consistency across servers.

FAQ

Why are all times in UTC?

So that data from servers in different time zones lines up consistently, and there's no daylight-saving ambiguity. Times are labelled "(UTC)" throughout.

Why does an idle server sometimes show as "Stale"?

If a server genuinely had no waits in a minute, no data is written for that minute, so the freshness check can briefly read as stale even though the collector is fine. Coverage and the background-jobs panel help you tell a quiet server from a stopped collector.

Why is my Wait Alerts page empty?

Either everything is within normal range (good), or the system is still learning. The baseline needs a few weeks of history before it raises alerts confidently — until then it stays deliberately quiet to avoid false alarms.

An alert fired but the number looks small — why?

Alerts are about deviation from normal, not absolute size. An hour that's small in absolute terms can still be flagged if it's far above what's normal for that server at that time — though a minimum floor prevents trivially tiny spikes from alerting.

The chart shows grouped bars instead of one stacked bar — is that wrong?

The chart is designed to be stacked (one bar per time slice). If you ever see separate side-by-side bars, refresh the page; it's a display glitch, not a data problem.

SQL Planner User Guide · For DBAs and IT Administrators · All times shown in UTC.
Scroll to Top