Server and Client Streaming
Bidirectional streaming and backpressure
Server and Client Streaming is a free Go Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Go Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
gRPC streaming types
gRPC supports three streaming modes beyond unary: server-streaming (server sends many), client-streaming (client sends many), and bidirectional (both stream).
Server streaming in .proto
Use the stream keyword before the response type:
service EventService {
rpc ListEvents (ListEventsRequest) returns (stream Event);
}Server streaming implementation
The server sends multiple messages by calling stream.Send() and returns nil when done:
func (s *server) ListEvents(req *pb.ListEventsRequest, stream pb.EventService_ListEventsServer) error {
for _, event := range s.events {
if err := stream.Send(event); err != nil { return err }
}
return nil
}Client receiving a server stream
The client calls Recv() in a loop until io.EOF:
stream, err := client.ListEvents(ctx, &pb.ListEventsRequest{})
for {
event, err := stream.Recv()
if err == io.EOF { break }
if err != nil { log.Fatal(err) }
fmt.Println(event)
}Client streaming in .proto
Use stream before the request type:
service UploadService {
rpc Upload (stream Chunk) returns (UploadResponse);
}Client streaming implementation
The client sends multiple messages then closes the stream with CloseAndRecv:
stream, _ := client.Upload(ctx)
for _, chunk := range chunks {
stream.Send(chunk)
}
resp, err := stream.CloseAndRecv()Server receiving client stream
Call stream.Recv() in a loop until io.EOF, then return the final response:
func (s *server) Upload(stream pb.UploadService_UploadServer) error {
for {
chunk, err := stream.Recv()
if err == io.EOF {
return stream.SendAndClose(&pb.UploadResponse{Received: total})
}
if err != nil { return err }
total += len(chunk.Data)
}
}Bidirectional streaming
Both client and server can send and receive independently. Declare with stream on both sides in the .proto.
service ChatService {
rpc Chat (stream Message) returns (stream Message);
}Bidirectional server implementation
Server receives in a goroutine and sends independently:
func (s *server) Chat(stream pb.ChatService_ChatServer) error {
for {
msg, err := stream.Recv()
if err == io.EOF { return nil }
if err != nil { return err }
stream.Send(&pb.Message{Text: "echo: " + msg.Text})
}
}Flow control
gRPC uses HTTP/2 flow control to prevent fast senders from overwhelming slow receivers. Calls to Recv() naturally apply back-pressure — sending blocks when the receiver is not reading.
Context cancellation
Pass a context with deadline or cancel to all streaming calls. The stream is cancelled when the context is done, which causes Recv/Send to return an error.
Quick Check
How does a server-streaming RPC server signal that it has finished sending?
Recap: gRPC Streaming
Key points:
- Server stream: stream keyword on response; server calls Send()
- Client stream: stream keyword on request; client calls Send() then CloseAndRecv()
- Bidirectional: stream on both; independent Send and Recv goroutines
- Context cancellation applies to all streaming calls
Frequently asked questions
Is the “Server and Client Streaming” lesson free?
Yes — the full text of “Server and Client Streaming” is free to read here on the web, and the Go Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Go Academy course, upgrade to CoddyKit PRO.
What will I learn in “Server and Client Streaming”?
Bidirectional streaming and backpressure You practise Go Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Go Academy?
No prior experience is required. Go Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Server and Client Streaming” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Go Academy lesson?
Yes. Every Go Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Protocol Buffers and .proto Files
- Implementing a Unary gRPC Service
- Server and Client Streaming
- gRPC Interceptors and Metadata