CXCONSUMER wait type – history and what you need to know

I’m a little bit overdue to blog about this new wait type, but I wanted to wait until SQL Server 2016 SP2 was released for a bit and people started seeing this new wait type.


Back in September 2016 I created a Connect item (3102145) to split the CXPACKET wait into benign and actionable waits, so that when a CXPACKET wait happens, there’s really something to investigate. Unfortunately the Connect website has been shut down by Microsoft so I can’t point you to the original request I made (I also tried in the Internet Archive but couldn’t find it).

The reason I wanted this change is that CXPACKET waits have always been registered by both producer and consumer threads for query plan operators where some threads produce data (i.e. producer threads) and some threads consume the produced data (i.e. consumer threads). However, the waits for the consumer threads are not actionable, because it’s the *producer* threads that are the cause of the consumer thread waits, and so it’s the producer thread waits that are actionable. By splitting the consumer waits out, the number of CXPACKET waits should be reduced, and those that are left should be investigated.

During the PASS Summit in 2017, my friend Pedro Lopes (b|t) on the Tiger Team announced that they’d made the change. The new wait type, CXCONSUMER, was initially added to SQL Server 2017 RTM CU3 and was added to SQL Server 2016 SP2 in April. You can read Pedro’s blog post here. Note that there was initially a bug with the implementation which was fixed in SQL Server 2017 RTM CU4.

What You Need To Know

CXCONSUMER waits can *generally* be ignored, but not always, just like most of the waits we generally ignore. I’ve seen control threads (thread ID = 0) show CXPACKET or CXCONSUMER, depending on what’s happening in the query plan, and I’ve seen some weird cases of skewed parallelism where everything shows as CXCONSUMER instead of CXPACKET. 

I’ve added a CXCONSUMER page to my waits library, and added it to the ‘ignore’ list in all published locations of my wait stats script. However, if you see a bunch of parallel threads on a long-running query accruing a lot of time waiting for CXCONSUMER, I’d troubleshoot it just like CXPACKET – look for skewed work distribution problems or something on the producer side of the parallel operator that’s stopping the producer threads from pushing through rows to the consumers efficiently.

PS And if you do have CXPACKET waits, start here. Don’t just blindly follow random internet advice to set your sp_configure ‘max degree of parallelism’ or ‘cost threshold for parallelism’ options so a set value without testing how it affects your workload and whether a higher or lower number is better for your environment.

4 thoughts on “CXCONSUMER wait type – history and what you need to know

  1. So does it mean that coordinator thread (id = 0) now registers CXCONSUMER wait type when it is waiting for other worker threads to finish their task? Or is it still CXPACKET?

Leave a Reply

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

Other articles

Imagine feeling confident enough to handle whatever your database throws at you.

With training and consulting from SQLskills, you’ll be able to solve big problems, elevate your team’s capacity, and take control of your data career.