← 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.
Syntax
go
ch := make(chan type, capacity)
ch <- value
value := <-ch

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
// Every Go file belongs to a package; main builds an executable
package main

// Import the fmt package
import "fmt"

// main is where the program starts running
func main() {
	// Short declaration: create ch and infer the type
	ch := make(chan int, 3)
	ch <- 1
	ch <- 2
	// Print the values followed by a newline
	fmt.Println("len:", len(ch), "cap:", cap(ch))
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
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.