← Back to Go Course | Chapter 11: Concurrency | Lesson 3 of 8

Buffered Channels

A buffered channel is like a mail slot with a little tray -- you can drop off a few messages even if nobody's home to grab them yet, up to the tray's limit.

Creating a Buffered Channel

Passing a second argument to make when creating a channel gives it a buffer, allowing that many values to be sent without a receiver being ready at that exact moment.

Example: Creating a Buffered Channel

markup
package main

import "fmt"

func main() {
	ch := make(chan int, 2)
	ch <- 1
	ch <- 2 // does not block: buffer has room for 2
	fmt.Println(<-ch)
	fmt.Println(<-ch)
}

Blocking Once the Buffer Is Full

A buffered channel isn't unlimited -- once its buffer is full, the next send still blocks until a receiver frees up space by taking a value out.

Example: Blocking Once the Buffer Is Full

markup
package main

import "fmt"

func main() {
	ch := make(chan int, 1)
	ch <- 10
	go func() {
		fmt.Println("received:", <-ch) // frees buffer space
	}()
	ch <- 20 // would block until the goroutine above receives
	fmt.Println("done")
}

Checking Length and Capacity

len(ch) tells you how many values are currently sitting in the buffer waiting to be received, while cap(ch) tells you the buffer's total capacity set when the channel was created.

Example: Checking Length and Capacity

markup
package main

import "fmt"

func main() {
	ch := make(chan int, 3)
	ch <- 1
	ch <- 2
	fmt.Println("len:", len(ch), "cap:", cap(ch))
}
Common Mistakes
  1. Assuming a buffered channel never blocks -- it still blocks once the buffer is full on send, or empty on receive.
  2. Choosing an arbitrary buffer size without reasoning about the actual production/consumption rate, masking a design problem instead of solving it.
  3. Confusing a channel's capacity (cap) with how many values are currently queued in it (len).
Chapter Summary
  • make(chan Type, n) creates a buffered channel that can hold up to n values without a receiver ready.
  • A send on a buffered channel only blocks once the buffer is full; a receive only blocks once it's empty.
  • len(ch) reports how many values are currently queued; cap(ch) reports the buffer's total capacity.
  • Buffered channels help decouple producers and consumers running at slightly different speeds.
🔒

Chapter Quiz — Complete all 8 topics to unlock

0/8 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.