mediumService Broker

BROKER_SERVICE Wait Type Explained

Fix SQL Server BROKER_SERVICE waits caused by Service Broker routing updates. Diagnostic queries, routing optimization scripts, and prevention strategies.

Quick Answer

BROKER_SERVICE waits occur when SQL Server updates or reprioritizes the destination list for Service Broker target services. This happens during route changes, service priority modifications, or when the routing table needs rebuilding. Generally low concern unless accumulated wait times are excessive or Service Broker message processing becomes slow.

Root Cause Analysis

The Service Broker routing infrastructure maintains destination lists that map target services to specific broker instances and routes. When these mappings require updates, the broker service component must acquire locks on internal routing structures and rebuild destination priority queues.

This wait type surfaces during several internal operations. Route table modifications trigger destination list rebuilds when ALTER ROUTE statements execute or when the routing algorithm detects topology changes. Service priority changes force reprioritization of existing destination entries, requiring sorted list reconstruction. Network connectivity issues can trigger route failover scenarios where backup destinations get promoted.

The routing subsystem uses a combination of shared memory structures and lock-free queues for performance. When contention occurs on these structures, threads wait with BROKER_SERVICE. SQL Server 2016 introduced optimizations that reduced lock granularity in the routing layer. SQL Server 2019 further improved this with lock-free destination list updates for common scenarios, though complex routing topologies still require exclusive access.

Internal routing table fragmentation can amplify these waits. Each service maintains multiple destination lists based on message priorities and conversation groups. Heavy message traffic combined with frequent route changes creates a scenario where the routing engine continuously rebuilds these structures.

Memory pressure affects this subsystem significantly. The broker service component allocates destination list memory from the general memory pool, not a dedicated broker memory region. When memory is constrained, the routing engine may perform more frequent cleanup operations, increasing wait occurrence.

AutoDBA checks Service Broker routing configuration, conversation cleanup patterns, and broker queue health monitoring across your entire SQL Server instance in 60 seconds. Download the free diagnostic script and see what else needs attention.

Diagnostic Queries

-- Check current Service Broker routing configuration
SELECT 
    r.name AS route_name,
    r.remote_service_name,
    r.broker_instance,
    r.address
FROM sys.routes r;

-- Check queue monitor status separately
SELECT 
    queue_name,
    state,
    last_activated_time,
    last_empty_rowset_time,
    tasks_waiting
FROM sys.dm_broker_queue_monitors;
-- Analyze Service Broker wait patterns and correlate with routing activity
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 LIKE 'BROKER%'
ORDER BY wait_time_ms DESC;
-- Examine active Service Broker conversations and their routing status
SELECT 
    c.conversation_handle,
    c.state_desc,
    c.far_service,
    c.far_broker_instance,
    e.message_type_name,
    COUNT(*) as pending_messages
FROM sys.conversation_endpoints c
LEFT JOIN sys.transmission_queue e ON c.conversation_handle = e.conversation_handle
GROUP BY c.conversation_handle, c.state_desc, c.far_service, c.far_broker_instance, e.message_type_name
HAVING COUNT(*) > 0;
-- Check for Service Broker routing errors and transmission failures
SELECT 
    tq.conversation_handle,
    tq.to_service_name,
    tq.to_broker_instance,
    tq.transmission_status,
    tq.message_body,
    ce.state_desc AS conversation_state
FROM sys.transmission_queue tq
JOIN sys.conversation_endpoints ce ON tq.conversation_handle = ce.conversation_handle
WHERE tq.transmission_status IS NOT NULL;
-- Monitor Service Broker queue monitor status
SELECT 
    bqm.database_id,
    DB_NAME(bqm.database_id) AS database_name,
    bqm.queue_name,
    bqm.state,
    bqm.tasks_waiting,
    bqm.last_activated_time,
    bqm.last_empty_rowset_time
FROM sys.dm_broker_queue_monitors bqm
WHERE bqm.tasks_waiting > 0;

Fix Scripts

Verify Service Broker routing health:

-- Review routes and check for any with problematic addresses
SELECT 
    name AS route_name,
    remote_service_name,
    broker_instance,
    address,
    mirror_address
FROM sys.routes
ORDER BY name;

-- Check transmission queue for routing failures
SELECT 
    conversation_handle,
    to_service_name,
    to_broker_instance,
    transmission_status
FROM sys.transmission_queue
WHERE transmission_status IS NOT NULL;

Clean up stale conversations causing routing overhead:

-- Identifies and ends conversations stuck in routing loops
-- Run during low activity periods, monitor for application impact
DECLARE @handle UNIQUEIDENTIFIER;
DECLARE conv_cursor CURSOR FOR
    SELECT ce.conversation_handle 
    FROM sys.conversation_endpoints ce
    WHERE ce.state IN ('DO', 'ER') -- Disconnected Outbound or Error states
    AND DATEDIFF(hour, ce.created_date, GETDATE()) > 24;

OPEN conv_cursor;
FETCH NEXT FROM conv_cursor INTO @handle;

WHILE @@FETCH_STATUS = 0
BEGIN
    END CONVERSATION @handle WITH CLEANUP;
    FETCH NEXT FROM conv_cursor INTO @handle;
END;

CLOSE conv_cursor;
DEALLOCATE conv_cursor;

Review and recreate routes if needed to reduce destination list churn:

-- List all current routes for review
SELECT name, remote_service_name, broker_instance, address 
FROM sys.routes 
ORDER BY name;

-- If routes need updating, drop and recreate them with correct addresses
-- DROP ROUTE [YourRouteName];
-- CREATE ROUTE [YourRouteName]
-- WITH SERVICE_NAME = 'YourServiceName',
-- ADDRESS = 'TCP://targetserver.domain.com:4022';

AutoDBA generates fix scripts like these automatically, with impact estimates and rollback SQL included.

Prevention

Configure Service Broker with stable routing topologies to minimize destination list updates. Use explicit routes rather than allowing automatic route discovery, which triggers frequent routing table rebuilds.

Monitor conversation endpoint cleanup patterns. Implement automated conversation cleanup procedures that run during maintenance windows rather than allowing conversations to accumulate and trigger emergency cleanup operations. Long-running conversations in error states consume routing table entries and increase lookup complexity.

Size the general memory pool appropriately for Service Broker workloads. The routing subsystem competes with other SQL Server components for memory, and memory pressure forces more frequent routing table maintenance operations. Monitor broker queue monitors DMV for memory-related activation delays.

Implement route health monitoring using transmission queue analysis. Proactively identify failing routes before they trigger failover scenarios that cause extensive destination list rebuilding. Use SQL Agent jobs to monitor transmission_status columns and alert on routing failures.

Consider partitioning Service Broker workloads across multiple databases when routing complexity grows beyond 50-100 routes per service. Complex routing topologies with frequent changes amplify BROKER_SERVICE waits exponentially as destination list maintenance becomes CPU-intensive.

Need hands-on help?

Dealing with persistent broker_service issues across your environment? Samix Technology provides hands-on SQL Server performance consulting with 15+ years of production DBA experience.

Related Pages