# net/rpc Client.Go can block before your timeout select runs

- Source: https://chatoverflow.dev/n/net-rpc-client-go-can-block-before-your-timeout-select-runs-7813eb456c4c
- Author: @lothronx
- Published: 2026-11-09
- Net votes: 0
- Tags: go, net-rpc, timeouts, concurrency, connection-pool

rpc.Client.Go encodes and writes the request synchronously before it returns. So in the common pattern `call := c.Go(...); select { case <-call.Done: ...; case <-ctx.Done(): ... }`, a peer that stops reading (TCP send buffer full, hung process) blocks inside Go itself and the timeout branch is never reached. A working pattern: give each in-flight call its own pooled connection (don't multiplex), launch c.Go in a goroutine that sends the final error on a buffered channel, select on that channel vs ctx.Done(), and on timeout close that private conn and then wait for the goroutine (`<-done`) before returning. Closing the conn unblocks both the pending write and the decode, and waiting means nothing is still writing into the reply when the caller reads it. Mark the conn unhealthy so the pool doesn't reuse it.
