Skip to content
API Design Learn/gRPC Fundamentals
Browsing as a guest. Sign in to save your progress and earn XP as you complete chapters.

Streaming RPCs

8 min read

You'll learn to

  • -Distinguish server streaming, client streaming, and bidirectional streaming, and match each to the right use case
  • -Explain what a stream's lifecycle looks like and how it differs from a single unary RPC call

A unary RPC (one request, one response) is what every gRPC example so far in this course has used - but gRPC, built on HTTP/2, natively supports three additional streaming modes that REST has no clean equivalent for, letting either side of a call send multiple messages over one long-lived connection instead of exactly one each.

Server Streaming: One Request, Many Responses

The server sends a stream of responses to one request
service StockService {
  rpc WatchPriceUpdates (WatchRequest) returns (stream PriceUpdate);
}

The client sends one `WatchRequest`, and the server keeps the connection open, pushing a new `PriceUpdate` message every time the price changes - a natural fit for exactly the kind of live-updating feed the GraphQL subscriptions chapter covered, just implemented over gRPC's native streaming instead of a WebSocket-based subscription protocol.

Client Streaming: Many Requests, One Response

The client sends a stream, the server responds once at the end
service UploadService {
  rpc UploadTelemetry (stream TelemetryPoint) returns (UploadSummary);
}

The client streams many `TelemetryPoint` messages (say, sensor readings collected over time) as they become available, and the server processes them incrementally, responding with one final `UploadSummary` once the client signals it has finished sending - useful when a client has a large or ongoing volume of data to send but doesn't need a response until the whole batch is processed.

Bidirectional Streaming: Both Sides, Independently

Both client and server stream messages, independently of each other
service ChatService {
  rpc Chat (stream ChatMessage) returns (stream ChatMessage);
}

Both sides send a stream of messages over the same connection, and - critically - the two streams are independent: the server doesn't have to wait for the client to finish sending before it starts responding, and either side can send at its own pace. This is the closest gRPC gets to a true full-duplex conversation, and it's the natural fit for something like a chat service where messages flow in both directions concurrently, not in strict request-then-response turns.

The Four RPC Types, at a Glance
One request, one response (the default, REST-equivalent shape)
Unary
One request, many responses (live feeds, subscriptions)
Server streaming
Many requests, one response (incremental uploads)
Client streaming
Both sides stream independently (chat, real-time collaboration)
Bidirectional

Stream Lifecycle

A stream has a clear lifecycle distinct from a single unary call: it opens, carries zero or more messages over time, and then closes - either side can close the stream (signaling "I'm done sending," not necessarily "the whole call is over," particularly in the bidirectional case where one side might finish sending well before the other does), and proper handling of that close signal on both sides is what prevents a stream from leaking a connection that neither side realizes should have ended.

Streaming RPCs hold a connection open for the stream's entire lifetime, which is a meaningfully different resource commitment than a unary call - at scale, this needs the same connection-management thinking as the WebSocket-backed GraphQL subscriptions covered earlier, not just "gRPC handles it automatically."

Interview Signal is part of Pro

See a real weak answer next to a real strong one for this exact topic.

Quiz is part of Pro

Test what you just read with a short quiz, and bank the XP.

Ready to Build This?

Design Stream Engine in the API Design Lab's gRPC & Event-Driven act.

ScaleDojo Logo
Initializing ScaleDojo