Skip to content

Buffered and bounded channels

Category: Communication · Status: stub · Lessons: chapter 05, Message passing (planned)

One line: A channel with a fixed-size buffer: sends succeed until it is full and then wait, which is how a slow receiver pushes back on a fast sender; an unbounded channel never waits and never pushes back.

Also called: buffered channel, bounded queue, unbounded channel, asynchronous channel.

How it connects

flowchart LR
  n_backpressure["Backpressure"]
  n_bounded_channel["Buffered and bounded channels"]
  n_channel["Channel"]
  n_producer_consumer["Producer-consumer"]
  n_unbuffered_channel["Unbuffered channel"]
  n_backpressure -->|uses| n_bounded_channel
  n_bounded_channel ---|vs| n_unbuffered_channel
  n_bounded_channel -->|is a| n_channel
  n_producer_consumer -->|uses| n_bounded_channel
  classDef center stroke-width:3px
  class n_bounded_channel center
  classDef outside stroke-dasharray: 4 3
  class n_backpressure,n_channel,n_producer_consumer,n_unbuffered_channel outside

In each language

Rust sync_channel(n) blocks senders when full, while channel() has an infinite buffer and never blocks the sender; tokio's mpsc offers both for async tasks
Go make(chan T, n): a send proceeds without blocking while the buffer is not full
Java ArrayBlockingQueue, a classic bounded buffer; LinkedBlockingQueue is optionally bounded
Python queue.Queue(maxsize) and asyncio.Queue(maxsize); a maxsize of zero or less means infinite
C# Channel.CreateBounded or CreateUnbounded; a BoundedChannelFullMode says whether a full channel waits, or drops the newest, the oldest or the item being written
Kotlin a capacity passed to Channel, or Channel.UNLIMITED; BufferOverflow chooses between suspending the sender and dropping a value
The operating system a pipe ↗ has a limited capacity, 16 pages by default on Linux: a write to a full pipe blocks, or fails if the pipe is non-blocking

Where to read more