How to create and use buffered channels in Golang

Introduction

We can specify a fixed capacity for a channel and create a buffered channel.

If the channel has a buffer, the sender will only block until the value has been pushed into the buffer. If the buffer is full, the sender blocks until a receiver retrieves a value.

Let us look at a worked-out example to further understand this concept.

package main
import "fmt"
func main() {
fmt.Printf("Hello World \n")
ch := make(chan string, 2)
ch <- "hello "
ch <- "golang"
fmt.Printf(<-ch)
fmt.Printf(<-ch)
}

In the above example, we see that we can send two values into channel ch without blocking since the capacity is 2.

Deadlock scenario

However, if we try to overfill the buffer, we will receive a deadlock error. This is shown in the example below.

package main
import "fmt"
func main() {
ch := make(chan int, 4)
ch <- 1
ch <- 2
ch <- 3
ch <- 4
ch <- 5
fmt.Println(<-ch)
fmt.Println(<-ch)
fmt.Println(<-ch)
fmt.Println(<-ch)
}

Uses of buffered channels

One of the main uses of buffered channels is to limit the number of workers queued up. This is particularly useful in network I/O or Disk I/O intensive compute scenarios.

New on Educative
Learn any Language for FREE all September 🎉
For the entire month of September, get unlimited access to our entire catalog of beginner coding resources.
🎁 G i v e a w a y
30 Days of Code
Complete Educative’s daily coding challenge every day in September, and win exciting Prizes.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved