Does a channel send wait for the receiver?

Read the explanation
What if

On an unbuffered channel, main's send waits until the receiver is ready to take the value.

Predict first

The receiver is busy for a moment. What does main do at ch <- "hello"?

012345678main: go receivergoch <- "hello"print sent<-donereturnbusy (time.Sleep)receiver: <-ch: hello<-chreceiver: print, close(done)close

Tap any block to see what that thread is doing.

  • Running
  • Waiting / parked
Step 1/5

main starts the receiver, which is busy for a while.

1func receiver(ch chan string, done chan struct{}) {2    time.Sleep(50 * time.Millisecond) // busy with something else3    msg := <-ch4    fmt.Println("received", msg)5    close(done)6}7 8func main() {9    ch := make(chan string) // unbuffered: no room to hold a value10    done := make(chan struct{})11    go receiver(ch, done)12 13    ch <- "hello"14    fmt.Println("sent")15    <-done16}

Explanation

What just happened

An unbuffered channel has no room to hold a value. So ch <- "hello" couldn’t finish until the receiver arrived at <-ch. main sat in [chan send] the whole time the receiver was busy. When the receiver got there, the value went straight across and both carried on.

That’s the point of an unbuffered channel: the send and the receive happen together, so the sender knows the value was taken.

Try the what-if switch

Which to use

Unbuffered when you want the handoff to sync the two goroutines. Buffered when the sender shouldn’t wait for each value, for example a queue of jobs.

Watch out

A buffer only moves the wait. Once it’s full, the next send waits exactly like an unbuffered one.

Common questions

Does sending on an unbuffered channel block?

Yes. The send waits until a receiver takes the value. A goroutine dump shows the sender as [chan send].

When does a buffered channel block?

A send waits only when the buffer is full, and a receive only when it's empty. With room left, ch <- v returns at once.

What is all goroutines are asleep - deadlock?

The Go runtime found every goroutine waiting, with nothing left that could wake any of them. It stops the program with this fatal error and exit code 2, and prints where each goroutine was waiting.

Verified: this timeline matches a real program, checked in CI on Go 1.26 and 1.27. How we verify. Unclear or wrong? Tell us