LCK_M_SCH_M is a wait to acquire a Schema Modification (SCH-M) lock. DDL needs this lock to change an object’s structure: ALTER TABLE, offline index rebuilds, partition switches, truncates, and drops all take SCH-M. It is the least compatible lock in the engine; it conflicts with every other lock, including the Schema Stability locks that every running query holds.
This wait means your DDL is stuck. Something is still using the object, and the schema change cannot start until every last reader and writer lets go.
Is It a Problem?
The wait itself hurts twice. First, the DDL is delayed. Second, and worse, while the SCH-M request queues, it blocks all new queries against the object from compiling, so a stuck ALTER TABLE quickly turns into an application-wide stall on that table. If LCK_M_SCH_M shows up in your top waits, deployments or maintenance are colliding with the workload.
Common Causes
- Running DDL while the application is active, with long-running queries or open transactions still holding locks on the object.
- Index maintenance jobs overlapping business hours, especially offline rebuilds.
- Partition switch or
TRUNCATE TABLEsteps in ETL waiting for readers to clear. - An idle session with an uncommitted transaction that touched the table hours ago.
What To Do
- When DDL hangs, check
sys.dm_os_waiting_tasksfor the SCH-M waiter and followblocking_session_idto the culprit.sys.dm_tran_locksshows what it still holds. - Kill or complete the blocker if it is an abandoned transaction;
DBCC OPENTRANin the database points at the oldest one. - Schedule DDL for quiet windows, and use
ONLINE = ONoperations where the edition allows, which need SCH-M only briefly at the start and end. - On SQL Server 2014 and later, use
WAIT_AT_LOW_PRIORITYwithABORT_AFTER_WAITso index operations fail fast or kill blockers deliberately, instead of freezing the table for everyone.
How To See It
Rank it against everything else with Get-WaitStatistics. LCK_M_SCH_M is spiky rather than constant, so line the spikes up with your job schedule and deployment history.
Part of the SQL Server Wait Types Library.
Related deep dive: LCK_M_X, LCK_M_S, and LCK_M_U Wait Types.
Leave a Reply