Go

How do you implement a timeout on a channel operation? Compare time.After, time.NewTimer, and context.

Question 198MediumGo 1.22 to 1.25
// 1. time.After: simplest, fine for one-off selects
select {
case v := <-ch:
	use(v)
case <-time.After(2 * time.Second):
	return errors.New("timeout")
}

// 2. Timer: reusable, stoppable
t := time.NewTimer(2 * time.Second)
defer t.Stop()
select {
case v := <-ch:
	use(v)
case <-t.C:
	return errors.New("timeout")
}

// 3. context: composes across call boundaries (preferred in services)
ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
defer cancel()
select {
case v := <-ch:
	use(v)
case <-ctx.Done():
	return ctx.Err() // context.DeadlineExceeded or Canceled
}

Trade-offs: time.After allocates a new timer on every call, which matters in hot loops (next question). NewTimer lets you Stop/Reset it. context is the idiomatic choice when the deadline should carry through to downstream calls (DB, HTTP) and cancel everything together. Interviewers want to hear "use context for request-scoped deadlines".

More on Channels & select

All 38 Channels & select questions