Bidirectional Streaming: Full-Duplex Communication with gRPC
SD
ScaleDojo
May 11, 2026
2 min read471 words
Google Maps Real-Time Navigation
Think about Google Maps navigation. Your phone continuously streams GPS coordinates to the server. Simultaneously, the server streams back turn-by-turn directions, traffic updates, and ETA changes. Both sides are sending data independently, at their own pace, on the same connection. This is bidirectional streaming - and gRPC makes it first-class.
The Four gRPC Communication Patterns
gRPC Streaming Modes:
1. Unary (like REST):
Client --[1 request]--> Server --[1 response]--> Client
Example: GetUser(id) -> User
2. Server Streaming:
Client --[1 request]--> Server --[stream of N responses]--> Client
Example: ListOrders(userId) -> Order, Order, Order, ...
3. Client Streaming:
Client --[stream of N requests]--> Server --[1 response]--> Client
Example: UploadChunks(chunk, chunk, ...) -> UploadResult
4. Bidirectional Streaming:
Client --[stream]--> <--[stream]-- Server
BOTH SIDES SEND INDEPENDENTLY
Example: Chat(messages...) <-> Chat(messages...)
Feature gRPC Bidi Stream WebSocket
---------------- ------------------- -------------------
Type safety Proto-defined msgs Raw bytes/text
Serialization Protobuf (binary) JSON (text) usually
Multiplexing Many streams on 1 1 channel per conn
HTTP/2 connection (needs own muxing)
Flow control Built-in (HTTP/2) Manual
Code generation Auto (protoc) Manual
Browser support No (needs proxy) Native
Backpressure Built-in Must implement
Use gRPC bidi: Service-to-service real-time
Use WebSocket: Browser-to-server real-time
Implementation Considerations
Pitfalls and Solutions:
1. Dead Connection Detection:
Problem: Client disconnects but server does not know
Solution: Keep-alive pings every 10-30 seconds
gRPC has built-in KEEPALIVE_TIME setting
2. Load Balancing:
Problem: Streaming connections are LONG-LIVED
Per-request balancing is impossible
Solution: Use connection-level balancing (L4)
OR client-side balancing with lookasides
3. Error Recovery:
Problem: Stream dies mid-conversation
Solution: Track last-processed sequence number
Reconnect and resume from that point
4. Memory Pressure:
Problem: Unbounded streams exhaust server memory
Solution: Flow control (HTTP/2 window updates)
Max message size limits (default 4MB)
Interview Tip
When a design question involves real-time service-to-service communication, say: 'For service-to-service real-time communication, I would use gRPC bidirectional streaming. Both sides can push messages independently on the same HTTP/2 connection, with type-safe Protobuf messages, built-in backpressure via flow control, and multiplexing of multiple streams on one connection. For browser clients, I would use WebSockets since gRPC is not natively supported in browsers without a proxy like grpc-web.'
<Architecture overview
/blockquote>
Key Takeaway
Bidirectional streaming allows independent, concurrent message flow between client and server. gRPC adds type safety, efficient serialization, and built-in flow control on top of full-duplex communication. Ideal for real-time features where both sides need to push data asynchronously.
No comments yet. Be the first to start the thread!
Related Articles
Enjoyed this content?
Your support keeps us creating free resources
We put a lot of hours into researching and writing these guides. If it helped you, consider buying us a coffee. Every bit goes toward keeping ScaleDojo's content free and growing.
$
One-time payment via Stripe. ScaleDojo account required.