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...)Protobuf Definition for Bidi Streaming
// navigation.proto
service NavigationService {
// Unary
rpc GetRoute(RouteRequest) returns (Route);
// Server streaming
rpc StreamTraffic(Area) returns (stream TrafficUpdate);
// Client streaming
rpc UploadTelemetry(stream TelemetryPoint)
returns (TelemetrySummary);
// Bidirectional streaming
rpc Navigate(stream LocationUpdate)
returns (stream NavigationInstruction);
}
message LocationUpdate {
double lat = 1;
double lng = 2;
float speed_kmh = 3;
int64 timestamp = 4;
}
message NavigationInstruction {
string direction = 1; // 'turn left in 200m'
float eta_minutes = 2;
TrafficLevel traffic = 3;
}How It Differs from WebSockets
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-timeImplementation 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.'
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.
