0
0
Goprogramming~5 mins

Buffered and unbuffered channels in Go

Choose your learning style9 modes available
Introduction

Channels let different parts of a Go program talk to each other safely. Buffered and unbuffered channels control how messages wait or pass instantly.

When you want to send data between two parts of a program without mixing them up.
When you want the sender to wait until the receiver is ready (unbuffered).
When you want the sender to send some messages and keep going without waiting (buffered).
When you want to control how many messages can wait before the receiver takes them.
When you want to avoid your program freezing because one part waits too long.
Syntax
Go
var ch chan int               // unbuffered channel
ch = make(chan int)           // create unbuffered channel

var chBuffered chan int
chBuffered = make(chan int, 3) // create buffered channel with capacity 3

An unbuffered channel has no space to hold messages; sender waits for receiver.

A buffered channel has space to hold some messages; sender waits only if buffer is full.

Examples
This example shows an unbuffered channel where send waits for receive.
Go
ch := make(chan int) // unbuffered channel
// Note: sending and receiving on unbuffered channels must be synchronized
// The following lines should be used with goroutines to avoid deadlock
// For example:
// go func() { ch <- 5 }()
// x := <-ch
This example shows a buffered channel where sends do not wait until buffer is full.
Go
ch := make(chan int, 2) // buffered channel with capacity 2
ch <- 1                 // send 1, does not wait
ch <- 2                 // send 2, does not wait
// ch <- 3 would wait here because buffer is full
x := <-ch               // receive first value
Sample Program

This program shows how unbuffered channels make the sender wait until the receiver gets the message, while buffered channels allow sending multiple messages without waiting until the buffer is full.

Go
package main

import (
	"fmt"
	"time"
)

func main() {
	// Unbuffered channel example
	unbuf := make(chan string)

	go func() {
		unbuf <- "hello"
		fmt.Println("Sent to unbuffered channel")
	}()

	time.Sleep(time.Second) // wait a bit
	msg := <-unbuf
	fmt.Println("Received from unbuffered channel:", msg)

	// Buffered channel example
	buf := make(chan string, 2)

	buf <- "hi"
	buf <- "there"
	fmt.Println("Sent two messages to buffered channel")

	fmt.Println("Received from buffered channel:", <-buf)
	fmt.Println("Received from buffered channel:", <-buf)
}
OutputSuccess
Important Notes

Unbuffered channels are good when you want strict synchronization between sender and receiver.

Buffered channels help improve performance by letting senders continue without waiting immediately.

Be careful: sending to a full buffered channel or receiving from an empty unbuffered channel blocks the program until the other side is ready.

Summary

Channels let parts of a Go program communicate safely.

Unbuffered channels make sender wait for receiver.

Buffered channels let sender send multiple messages without waiting until buffer is full.