Quick Answer
BROKER_SHUTDOWN occurs when SQL Server's Service Broker component initiates a planned shutdown sequence. This wait type appears during controlled shutdowns of Service Broker endpoints, typically lasting milliseconds during SQL Server restarts, database shutdowns, or explicit Service Broker disable operations.
Root Cause Analysis
BROKER_SHUTDOWN manifests when the Service Broker task scheduler coordinates the orderly termination of broker services. The wait occurs specifically in the broker shutdown thread as it signals dependent components (conversation endpoints, transmission queues, route tables) to cease operations and flush pending messages.
During shutdown, the Service Broker subsystem must complete several critical operations: drain the transmission queue, close active conversation handles, persist conversation state to disk, and notify remote brokers of endpoint closures. The scheduler waits for acknowledgment from these subsystems before marking the broker as fully shut down.
In SQL Server 2016 and later, this process includes additional validation of Always On Availability Group message routing states. SQL Server 2019 introduced enhanced logging for broker shutdown sequences, making troubleshooting more granular. SQL Server 2022 optimized the shutdown sequence to reduce the duration of these waits through improved parallelization of cleanup tasks.
The wait becomes problematic when Service Broker cannot cleanly shut down due to blocked conversations, corrupted transmission queues, or hung remote connections. Extended BROKER_SHUTDOWN waits often indicate underlying network connectivity issues or deadlocked conversation endpoints that prevent graceful termination.
AutoDBA checks Service Broker conversation health, transmission queue monitoring, and endpoint configuration validation across your entire SQL Server instance in 60 seconds. Download the free diagnostic script and see what else needs attention.
Diagnostic Queries
-- Check active Service Broker conversations and their states
SELECT
c.conversation_handle,
c.state_desc,
c.far_service,
c.dialog_timer,
s.name AS service_name
FROM sys.conversation_endpoints c
JOIN sys.services s ON c.service_id = s.service_id
WHERE c.state NOT IN ('CD', 'CL');
-- Examine transmission queue for stuck messages
SELECT
q.conversation_handle,
q.message_type_name,
q.message_body,
q.enqueue_time,
q.transmission_status
FROM sys.transmission_queue q
ORDER BY q.enqueue_time;
-- Monitor current Service Broker wait statistics
SELECT
wait_type,
waiting_tasks_count,
wait_time_ms,
max_wait_time_ms,
signal_wait_time_ms
FROM sys.dm_os_wait_stats
WHERE wait_type LIKE 'BROKER%'
ORDER BY wait_time_ms DESC;
-- Check Service Broker endpoint status and configuration
SELECT
e.name,
e.state_desc,
e.is_message_forwarding_enabled,
te.port,
te.ip_address
FROM sys.service_broker_endpoints e
JOIN sys.tcp_endpoints te ON e.endpoint_id = te.endpoint_id;
-- Review SQL Server error log for Service Broker messages
EXEC sp_readerrorlog 0, 1, N'Service Broker';
Fix Scripts
Force conversation cleanup for stuck endpoints:
-- Identifies and terminates conversations that may be blocking shutdown
-- WARNING: This ends conversations forcefully and may cause message loss
DECLARE @conversation_handle UNIQUEIDENTIFIER;
DECLARE cleanup_cursor CURSOR FOR
SELECT conversation_handle
FROM sys.conversation_endpoints
WHERE state_desc NOT IN ('CD', 'CL');
OPEN cleanup_cursor;
FETCH NEXT FROM cleanup_cursor INTO @conversation_handle;
WHILE @@FETCH_STATUS = 0
BEGIN
END CONVERSATION @conversation_handle WITH CLEANUP;
FETCH NEXT FROM cleanup_cursor INTO @conversation_handle;
END;
CLOSE cleanup_cursor;
DEALLOCATE cleanup_cursor;
Clear transmission queue by ending stuck conversations:
-- Ends conversations with stuck messages in the transmission queue
-- This causes Service Broker to clean up the associated queue messages
-- Test in development first, as this discards pending messages
DECLARE @conv UNIQUEIDENTIFIER;
DECLARE queue_cursor CURSOR FOR
SELECT DISTINCT conversation_handle
FROM sys.transmission_queue
WHERE enqueue_time < DATEADD(HOUR, -24, GETUTCDATE())
OR transmission_status LIKE '%error%';
OPEN queue_cursor;
FETCH NEXT FROM queue_cursor INTO @conv;
WHILE @@FETCH_STATUS = 0
BEGIN
END CONVERSATION @conv WITH CLEANUP;
FETCH NEXT FROM queue_cursor INTO @conv;
END;
CLOSE queue_cursor;
DEALLOCATE queue_cursor;
Reset Service Broker endpoints:
-- Disable and re-enable Service Broker to force clean state
-- This requires exclusive database access
ALTER DATABASE [YourDatabaseName] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
ALTER DATABASE [YourDatabaseName] SET DISABLE_BROKER;
ALTER DATABASE [YourDatabaseName] SET ENABLE_BROKER;
ALTER DATABASE [YourDatabaseName] SET MULTI_USER;
Configure timeout values to prevent hanging shutdowns:
-- Set conversation lifetime to prevent indefinite waits
-- Adjust timeout values based on your application requirements
DECLARE @dialog_handle UNIQUEIDENTIFIER;
BEGIN DIALOG @dialog_handle
FROM SERVICE [YourService]
TO SERVICE 'YourTargetService'
WITH LIFETIME = 3600; -- 1 hour timeout
AutoDBA generates fix scripts like these automatically, with impact estimates and rollback SQL included.
Prevention
Monitor Service Broker conversation health proactively using SQL Server Agent jobs that check for conversations stuck in error states longer than your application's expected message processing time. Set up alerts for transmission queue depth exceeding normal operational thresholds.
Configure proper conversation lifetime values during dialog creation to prevent indefinite conversation states. Applications should implement proper error handling that explicitly ends conversations when business logic failures occur, rather than leaving them in indeterminate states.
Implement connection pooling for Service Broker applications to reduce the overhead of conversation establishment and teardown. This minimizes the likelihood of orphaned conversations during application failures.
For Always On environments, ensure Service Broker routing tables are properly synchronized across replicas. Misconfigured routing often leads to conversations that cannot be cleanly terminated during failover scenarios.
Set up monitoring for the BROKER_SHUTDOWN wait type with thresholds above 5 seconds, as extended waits typically indicate underlying Service Broker health issues that require immediate attention.
Need hands-on help?
Dealing with persistent broker_shutdown issues across your environment? Samix Technology provides hands-on SQL Server performance consulting with 15+ years of production DBA experience.