Every producer/consumer queue I've written in the last few years sits on System.Threading.Channels, and nearly every one starts with Channel.CreateUnbounded. It's the overload that asks no questions. No capacity to pick, no full-queue policy to design, WriteAsync never waits. Last week I caught myself typing it into yet another background worker and realized I'd never measured what that convenience costs when the consumer falls behind.

So I built the smallest pipeline that could embarrass me.

The setup

One producer, one consumer, 100,000 work items, each carrying a 2 KB payload — think serialized webhook deliveries waiting to go out. The consumer burns roughly 20 µs of simulated work per item (checksum passes standing in for serialize-and-send), so the producer is far faster than the consumer. That's the whole experiment: a burst arriving quicker than it drains.

var channel = Channel.CreateUnbounded<WorkItem>(