HTTP is not duplex (the Spur mistake)
HTTP is half-duplex request-response. Client speaks, then server speaks. There is no protocol-level way for the server to push without the client asking.
HTTP is half-duplex at the semantic level. The client sends a request, then the server sends a response. There is no built-in mechanism for the server to initiate a message. If you want real bidirectional, you need WebSocket, SSE, gRPC streaming, or long polling.
Why this trips people up
HTTP/1.1 runs over TCP, which is full-duplex. So you can technically write bytes both ways at the same time on the socket. But the HTTP protocol on top is strictly request-then-response. The server cannot say "hey by the way here is an event" unless the client asked.
HTTP/2 multiplexes streams, and a stream's request body and response body can flow concurrently (this is what gRPC bidi streaming uses). But the lifecycle is still: client opens stream with HEADERS, server answers. Server cannot open new streams to push events outside server push (deprecated).
The Spur interview moment
What people use for real bidirectional
- WebSocket: upgrade from HTTP, then symmetric framing. Both sides send anytime.
- Server-Sent Events: HTTP response that never ends, server pushes lines of text. One direction (server to client).
- gRPC bidi streaming: client and server both stream over an HTTP/2 stream.
- Long polling: client holds a GET open until server has data. Fakes push.
Why HTTP stayed half-duplex
HTTP was designed for documents. You ask for a page, you get a page. Push was retrofitted (HTTP/2 server push, removed from Chrome 2022) and never worked well. The right answer was always WebSocket or a streaming protocol on top.
What to say in interviews
"HTTP is half-duplex by design. The transport (TCP or QUIC) is full-duplex but the protocol semantics are strictly request-response. For real-time bidirectional you upgrade to WebSocket or use gRPC bidi streaming over HTTP/2."
Learn more
- Paper
- Paper
- Docs