Karthik Menon
2 min read

Reading SQL Server Wait Statistics Without Guessing

SQL ServerPerformance Tuning

Wait statistics are one of the first things I check when a SQL Server instance "feels slow." CPU and disk graphs can point in a direction, but sys.dm_os_wait_stats (or sys.dm_exec_session_wait_stats for a single session) tells you what SQL Server itself has been waiting on since the last restart or stats reset.

Start with a clean baseline

Wait stats accumulate from the moment the instance starts, so before drawing conclusions I clear them (in a non-production-impacting way, or by comparing deltas) and let the workload run for a representative window:

-- Clear wait stats to get a clean window (use with care, and understand your workload cycle first)
DBCC SQLPERF('sys.dm_os_wait_stats', CLEAR);

Group waits into categories, not raw wait types

Raw wait types are noisy - some are always present and not actionable (like SLEEP_TASK in idle periods). I group waits into rough categories before drawing conclusions:

  • CPU pressure: SOS_SCHEDULER_YIELD, high signal wait time relative to resource wait time.
  • I/O pressure: PAGEIOLATCH_*, WRITELOG.
  • Blocking: LCK_M_* wait types.
  • Memory pressure: RESOURCE_SEMAPHORE.

A basic architecture for ongoing monitoring

Why this matters

Wait statistics don't replace execution plan analysis or index review - they point you toward which of those to prioritize. Treating them as a triage step rather than a final answer has saved me from chasing the wrong fix more than once.

More posts on SQL Server performance, AWS architecture, and AI-assisted DBA automation are on the way.