LATCH_SH Wait Type in SQL Server

⏳Part of the SQL Server Wait Types Library, every wait type explained.Related deep dive: PAGELATCH_EX, TempDB Allocation ContentionRelated pillar: Performance & Troubleshooting
⚡LATCH_SH is a thread waiting to read an internal structure that is not a data page, because another thread holds it exclusively. The name does not say which structure; the latch class does. Run the latch class query and work from the class at the top.

Microsoft’s definition: waiting for an SH (share) latch, not including buffer latches or transaction mark latches. The thread wants to read a non-page structure and cannot because another thread has it latched in exclusive mode. Shared latches are compatible with keep, shared and update in the latch compatibility table, so the blocker is an exclusive or destroy latch.

sys.dm_os_latch_stats groups all the LATCH_* modes together per class, so the analysis is the same as for LATCH_EX: find the class, then fix the subsystem it names.


Is It a Problem?

Low values are normal. Sustained high LATCH_SH means many readers are queuing on one internal structure, usually alongside LATCH_EX on the same class, because readers and writers of one hot structure queue together. On our SQL Server 2025 lab it had about 10,600 waits averaging 8 ms. Get Wait Statistics does not filter it out, so if it ranks, you will see it.

Judge it over an interval rather than the cumulative totals. The baseline to monitor is the top latch class’s wait_time_ms between two readings.


The Check To Run

Rank it against everything else with Get Wait Statistics, then break the latch time down by class:

SELECT
    latch_class,
    waiting_requests_count,
    wait_time_ms,
    max_wait_time_ms
FROM sys.dm_os_latch_stats
WHERE latch_class <> 'BUFFER'
ORDER BY wait_time_ms DESC;

The top row is your lead. BUFFER is left out because page latches belong to the PAGELATCH and PAGEIOLATCH pages. The view is cumulative since restart; for a before and after test, clear it with DBCC SQLPERF ('sys.dm_os_latch_stats', CLEAR);. It needs VIEW SERVER STATE.


What To Do

  1. Match the top class to its row in the LATCH_EX class table, which has the documented causes and fixes: ACCESS_METHODS_DATASET_PARENT for parallel scans, ACCESS_METHODS_HOBT_VIRTUAL_ROOT for root splits, the allocation cache classes for concurrent inserts, FGCB_ADD_REMOVE for file growth.
  2. For a parallel scan class, review MAXDOP and cost threshold and index the queries driving the scans.
  3. If the class is documented as internal use only and it dominates for long, a support case is the honest next step.

The LATCH Family

Each latch mode has its own wait type, and the mode only says how the latch was asked for. The latch view groups the modes into a single row per class, so whichever of these you landed on, the check is the same.

  • LATCH_KPKeep. Pins the structure so nothing can destroy it; compatible with every mode except DT.Usually noise
  • LATCH_SHShared. Reading the structure, any number of readers at once, queueing behind a writer.Usually noise. This page.
  • LATCH_UPUpdate. About to modify; allows SH and KP alongside it and nothing else.Usually noise
  • LATCH_EXExclusive. Blocks every other reader and writer of the structure.Worth investigating
  • LATCH_DTDestroy. Taken before the structure is torn down.Usually noise
  • LATCH_NLNull. Documented for information only, not supported.Usually noise

Where To Go Next

If LATCH_SH is sitting near the top of your wait stats, these are the next places to look.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *