What is bidirectional streaming in gRPC and how does it work?
Learn what gRPC bidirectional streaming is, how full-duplex HTTP/2 streams work, proto syntax, code examples and common interview questions with clear answers.
Expected Interview Answer
Bidirectional streaming in gRPC is an RPC mode where the client and server each send a stream of messages over a single long-lived HTTP/2 connection, reading and writing independently and concurrently rather than in a strict request-then-response pattern.
It is declared in the .proto file with the stream keyword on both the request and response types. Under the hood gRPC multiplexes both message streams over one HTTP/2 stream, so either side can send whenever it has data — the ordering within each direction is preserved, but the two directions are decoupled. This makes it ideal for chat, real-time telemetry, live collaboration, or any workload where messages flow continuously in both directions.
- Full-duplex communication over one connection
- Low latency — no wait for a full request before responding
- Reuses a single HTTP/2 stream, avoiding repeated handshakes
- Independent, order-preserving streams in each direction
- Natural fit for real-time and long-lived interactions
AI Mentor Explanation
Bidirectional streaming is like the constant chatter between a batter and the non-striker during an over: both call 'yes', 'no', 'wait' continuously and independently as each ball is bowled, neither waiting for the other to finish before speaking, yet both stay perfectly in sync run after run over one shared partnership.
Step-by-Step Explanation
Step 1
Declare the RPC
In the .proto file, mark both the request and response with the stream keyword: rpc Chat(stream Msg) returns (stream Msg).
Step 2
Generate code
protoc produces a stub whose method returns a stream object that can both send and receive messages.
Step 3
Open the stream
The client calls the method, establishing a single long-lived HTTP/2 stream to the server.
Step 4
Send and receive concurrently
Each side runs independent read and write loops, sending messages whenever ready without blocking the other direction.
Step 5
Half-close and finish
When a side is done sending it closes its write half; the RPC completes once both directions finish and a status is returned.
What Interviewer Expects
- Knowing the stream keyword goes on both sides in the .proto
- Understanding HTTP/2 multiplexing underpins it
- That the two directions are independent and concurrent
- Awareness of real use cases like chat or telemetry
- Difference from unary and server/client streaming
Common Mistakes
- Thinking messages must alternate strictly request-then-response
- Believing it opens two separate TCP connections
- Confusing it with server-streaming or client-streaming only
- Forgetting that each side must half-close its stream
- Assuming ordering is guaranteed across both directions rather than within each
Best Answer (HR Friendly)
“Bidirectional streaming lets the client and server send messages to each other continuously over one open connection, like a phone call where both people can talk and listen at the same time. It is great for real-time features such as chat or live updates.”
Code Example
service ChatService {
// stream on BOTH sides = bidirectional
rpc Chat(stream ChatMessage) returns (stream ChatMessage);
}
message ChatMessage {
string user = 1;
string text = 2;
}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
}
// echo back concurrently
if err := stream.Send(&pb.ChatMessage{User: "server", Text: msg.Text}); err != nil {
return err
}
}
}Follow-up Questions
- How does HTTP/2 multiplexing enable bidirectional streaming?
- What is the difference between client, server and bidirectional streaming?
- How do you handle flow control and backpressure in a stream?
- How would you cancel or time out a long-lived stream?
- What happens when one side closes its half of the stream?
MCQ Practice
1. Which .proto declaration defines a bidirectional streaming RPC?
The stream keyword must appear on both the request and the response for bidirectional streaming.
2. What underlying protocol feature makes gRPC bidirectional streaming possible?
gRPC runs on HTTP/2, whose multiplexed streams allow full-duplex message flow over one connection.
3. In bidirectional streaming, message ordering is guaranteed:
Ordering is preserved within each direction, but the two directions are independent of each other.
Flash Cards
How is bidirectional streaming declared? — With the stream keyword on both the request and response types in the .proto rpc definition.
What transport enables it? — HTTP/2, using multiplexed streams for full-duplex communication over one connection.
Are the two directions synchronized? — No — each side sends independently and concurrently; ordering is preserved only within each direction.
A typical use case? — Real-time chat, live telemetry, gaming, or collaborative editing where messages flow both ways continuously.