Overview
Unary and streaming are the two call shapes gRPC (and similar RPC frameworks) support over HTTP/2. A unary call behaves like a classic function call — one request in, one response out, then done — while a streaming call keeps the connection open so either side can send multiple messages over time. The choice affects latency, backpressure handling, and how errors surface mid-exchange.
Comparison Diagram
Comparison Table
| Aspect | Unary RPC | Streaming RPC |
|---|---|---|
| Call initiation | Client opens the call and immediately sends the complete request | Client opens the call, which may send zero, one, or many messages before or while reading responses |
| Client-to-server messages | Exactly one request message per call | One (server-streaming) or many (client-streaming, bidi) messages per call |
| Server-to-client messages | Exactly one response message per call | One (client-streaming) or many (server-streaming, bidi) messages per call |
| Flow control | Not needed — a single frame per direction fits within normal HTTP/2 windows | HTTP/2 flow-control windows and backpressure govern how fast messages can be sent |
| Connection/call lifetime | Logically short-lived: opens and closes within one round trip | Can stay open for the duration of a long-running exchange, sometimes indefinitely |
| Latency and overhead | Full connection/setup overhead paid per call since each call is independent | Setup overhead amortized across many messages, lowering per-message latency |
| Termination and errors | A single status code ends the call atomically — it either succeeded or failed | Status is sent only when the stream closes; errors can occur mid-stream after partial data was already delivered |
Key Differences
- Unary sends exactly one request and gets exactly one response, while streaming allows either side to send a sequence of messages over the same call
- Streaming relies on HTTP/2 flow control to manage backpressure across many frames; unary has nothing to manage
- A streaming call’s connection stays open far longer than a unary call’s brief request-response window
- Unary calls fail or succeed as a single atomic unit; streaming calls can deliver partial results before an error terminates them
- Streaming amortizes per-call overhead across many messages, cutting per-message latency compared to repeated unary calls
When to Use Each
Unary RPC
- Simple CRUD operations: A single lookup or update maps naturally to one request and one response with no ongoing state.
- REST-like API parity: Unary calls mirror the request/response semantics developers already expect from HTTP APIs, easing adoption.
- Idempotent, retryable actions: A self-contained request/response pair is easy to retry safely on failure or timeout.
Streaming RPC
- Real-time server push: Server-streaming lets a service push live updates (e.g. price ticks, logs) without the client polling repeatedly.
- Large payload chunking: Client-streaming lets a client upload large data (e.g. a file) as a sequence of chunks instead of one huge message.
- Bidirectional interactive exchange: Bidi streaming supports chat, telemetry, or negotiation protocols where both sides send messages independently and continuously.