Quick Answer
LCK_M_SIX_LOW_PRIORITY occurs when a session waits for a Shared with Intent Exclusive lock using the LOW_PRIORITY option. This happens during online index rebuilds or schema modifications that must wait for existing readers to complete. Generally indicates healthy behavior during controlled maintenance operations.
Root Cause Analysis
This wait type exists exclusively within SQL Server's lock manager when using the LOW_PRIORITY locking mechanism introduced in SQL Server 2014. When ALTER INDEX REBUILD ONLINE or ALTER TABLE operations specify WAIT_AT_LOW_PRIORITY, the lock manager places these requests in a separate low-priority queue within the lock compatibility matrix.
The SIX lock (Shared with Intent Exclusive) allows concurrent shared locks while preventing new exclusive locks. During online index operations, SQL Server needs SIX locks on the target table to maintain data consistency while allowing reads. The LOW_PRIORITY suffix indicates the lock request voluntarily yields to existing and new shared lock requests for a specified duration.
SQL Server's lock manager maintains separate escalation paths for low-priority requests. When the wait timeout expires without acquiring the lock, the system either kills conflicting sessions (if KILL_SELF_BLOCKERS is specified) or aborts the operation (if SELF is specified). This mechanism prevents maintenance operations from blocking production workloads indefinitely.
The wait manifests in sys.dm_os_wait_stats when the lock manager places the requesting session into a suspended state. Unlike standard SIX waits, these requests don't participate in deadlock detection during the low-priority phase, which can create unusual blocking chains if multiple low-priority operations overlap.
Version differences are minimal since 2014, though SQL Server 2016 improved the internal queuing mechanism to better handle multiple concurrent low-priority requests on the same resource.
AutoDBA checks Low-priority lock configurations, maintenance window optimization, and blocking session analysis across your entire SQL Server instance in 60 seconds. Download the free diagnostic script and see what else needs attention.
Diagnostic Queries
-- Check current low-priority lock waits and blocking
SELECT
r.session_id,
r.wait_type,
r.wait_time,
r.blocking_session_id,
s.program_name,
r.command,
t.text
FROM sys.dm_exec_requests r
INNER JOIN sys.dm_exec_sessions s ON r.session_id = s.session_id
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE r.wait_type = 'LCK_M_SIX_LOW_PRIORITY';
-- Examine lock requests and compatibility for LOW_PRIORITY operations
SELECT
l.request_session_id,
l.resource_type,
l.resource_database_id,
l.resource_associated_entity_id,
l.request_mode,
l.request_type,
l.request_status,
OBJECT_NAME(p.object_id, l.resource_database_id) AS object_name
FROM sys.dm_tran_locks l
LEFT JOIN sys.partitions p ON l.resource_associated_entity_id = p.hobt_id
WHERE l.request_mode = 'SIX'
AND l.request_session_id IN (
SELECT session_id FROM sys.dm_exec_requests
WHERE wait_type = 'LCK_M_SIX_LOW_PRIORITY'
);
-- Find active index operations that might be causing these waits
SELECT
ixs.session_id,
ixs.command,
ixs.percent_complete,
ixs.start_time,
ixs.estimated_completion_time,
OBJECT_NAME(ixs.database_id) AS database_name,
OBJECT_NAME(ddmid.object_id, ddmid.database_id) AS table_name
FROM sys.dm_exec_requests ixs
LEFT JOIN sys.dm_db_missing_index_details ddmid ON ixs.plan_handle = ddmid.plan_handle
WHERE ixs.command LIKE '%INDEX%'
OR ixs.command LIKE '%ALTER%';
-- Check wait statistics history for LOW_PRIORITY patterns
SELECT
wait_type,
waiting_tasks_count,
wait_time_ms,
max_wait_time_ms,
signal_wait_time_ms,
wait_time_ms / NULLIF(waiting_tasks_count, 0) AS avg_wait_ms
FROM sys.dm_os_wait_stats
WHERE wait_type = 'LCK_M_SIX_LOW_PRIORITY'
AND waiting_tasks_count > 0;
-- Identify sessions holding shared locks that block low-priority operations
SELECT DISTINCT
l.request_session_id,
s.program_name,
s.host_name,
l.resource_type,
OBJECT_NAME(p.object_id, l.resource_database_id) AS blocked_object,
l.request_mode
FROM sys.dm_tran_locks l
INNER JOIN sys.dm_exec_sessions s ON l.request_session_id = s.session_id
LEFT JOIN sys.partitions p ON l.resource_associated_entity_id = p.hobt_id
WHERE l.resource_associated_entity_id IN (
SELECT DISTINCT resource_associated_entity_id
FROM sys.dm_tran_locks
WHERE request_session_id IN (
SELECT session_id FROM sys.dm_exec_requests
WHERE wait_type = 'LCK_M_SIX_LOW_PRIORITY'
)
)
AND l.request_mode IN ('S', 'IS')
AND l.request_status = 'GRANT';
Fix Scripts
Adjust LOW_PRIORITY timeout settings Increases the wait duration before escalating lock priority, giving more time for readers to complete naturally.
-- Modify existing ALTER INDEX operation with longer LOW_PRIORITY wait
-- TEST IN DEVELOPMENT FIRST - Affects production index rebuild duration
ALTER INDEX [IX_YourIndex] ON [dbo].[YourTable]
REBUILD ONLINE = ON (
WAIT_AT_LOW_PRIORITY (
MAX_DURATION = 10 MINUTES, -- Increased from default
ABORT_AFTER_WAIT = BLOCKERS -- Kill blocking sessions after timeout
)
);
Kill blocking sessions for urgent maintenance Terminates sessions holding shared locks that prevent low-priority operations from proceeding.
-- CAUTION: This kills active user sessions - coordinate with application teams
DECLARE @sql NVARCHAR(MAX) = '';
SELECT @sql = @sql + 'KILL ' + CAST(request_session_id AS VARCHAR(10)) + ';' + CHAR(13)
FROM sys.dm_tran_locks l
WHERE l.resource_associated_entity_id IN (
SELECT DISTINCT resource_associated_entity_id
FROM sys.dm_tran_locks
WHERE request_session_id IN (
SELECT session_id FROM sys.dm_exec_requests
WHERE wait_type = 'LCK_M_SIX_LOW_PRIORITY'
)
)
AND l.request_mode IN ('S', 'IS')
AND l.request_status = 'GRANT'
AND l.request_session_id > 50; -- Avoid system sessions
-- Review generated script before executing
PRINT @sql;
-- EXEC sp_executesql @sql; -- Uncomment to execute
Cancel low-priority operation Stops the maintenance operation to restore normal database access immediately.
-- Find and cancel the low-priority operation
DECLARE @session_id INT;
SELECT @session_id = session_id
FROM sys.dm_exec_requests
WHERE wait_type = 'LCK_M_SIX_LOW_PRIORITY';
IF @session_id IS NOT NULL
BEGIN
DECLARE @kill_cmd NVARCHAR(50) = 'KILL ' + CAST(@session_id AS VARCHAR(10));
PRINT 'Canceling session: ' + @kill_cmd;
EXEC sp_executesql @kill_cmd;
END;
Resume operation with different LOW_PRIORITY strategy Restarts the maintenance with SELF termination instead of killing blockers.
-- Restart with SELF abort strategy - operation fails instead of killing users
-- Safer for production environments during business hours
ALTER INDEX [IX_YourIndex] ON [dbo].[YourTable]
REBUILD ONLINE = ON (
WAIT_AT_LOW_PRIORITY (
MAX_DURATION = 5 MINUTES,
ABORT_AFTER_WAIT = SELF -- Abort operation instead of killing blockers
)
);
AutoDBA generates fix scripts like these automatically, with impact estimates and rollback SQL included.
Prevention
Schedule maintenance operations during low-activity periods when fewer shared locks exist. Use application connection pooling with shorter connection timeouts to reduce lock duration. Monitor sys.dm_db_index_usage_stats to identify maintenance windows with minimal read activity.
Configure LOW_PRIORITY operations with ABORT_AFTER_WAIT = SELF during business hours to prevent user session termination. Reserve BLOCKERS strategy for planned maintenance windows with proper user notification. Set MAX_DURATION based on historical lock hold times from sys.dm_tran_locks monitoring.
Implement query hints like READPAST or NOLOCK for reporting queries that can tolerate slightly stale data during maintenance windows. Use database snapshots for consistent reporting views that don't hold shared locks on production tables.
Consider partitioning large tables to enable partition-level maintenance operations that require fewer extensive locks. Online index rebuilds on partitioned tables can process individual partitions, reducing the scope of SIX locks needed.
Monitor blocking chains through sys.dm_os_waiting_tasks before scheduling maintenance. Establish operational procedures to identify long-running queries that should complete before starting low-priority operations.
Need hands-on help?
Dealing with persistent lck_m_six_low_priority issues across your environment? Samix Technology provides hands-on SQL Server performance consulting with 15+ years of production DBA experience.