gRPC transportsenior8+ years

gRPC documentation says one HTTP/2 connection can carry many concurrent calls, streaming and unary alike. What actually makes that true at the protocol level, and where does it stop being true?

gRPC opens one HTTP/2 connection per target and represents every call — whether unary or one of the three streaming shapes — as its own HTTP/2 stream, a sequence of frames carrying a shared stream ID that get interleaved with frames from every other in-flight call on that same connection. That's genuinely different from HTTP/1.1, where a client wanting several requests in flight at once needs several separate TCP connections, because one HTTP/1.1 connection can only carry one request-response at a time. It stops being true one layer down: every one of those streams still travels over the same single TCP connection's ordered byte delivery, so if one packet is lost, the whole connection stalls — every stream's frames, not just the one that was mid-transfer — until that packet is retransmitted. Multiplexing removes the request-level blocking; it doesn't remove TCP's own blocking underneath it.

The lesson behind it →