but stateful connection management comes with a cost, especially on tcp.
TCP has stateful connections, but both HTTP versions are being sent over TCP anyway so in that sense the transport was always stateful.
It is not currently. HTTP/2 header compression is stateful.
HTTP/2 is a protocol that appear stateless to the end user.
Http/2 is multiplexed, unlike http/0.9-1.1, and while that has some overhead, it being a binary protocol probably makes up for it.
i.e.: https://http2.github.io/http2-spec/#StreamStates of course the "user layer" is stateless, but the whole connection handling is a state machine (which actually http/0.9-1.1 wasn't)
Keep-alive isn't any better. In Apache bad nginx, keep-alive and http/2 parallel requests are handled at a separate thread and hardly adds any noticeable load.
TCP has stateful connections, but both HTTP versions are being sent over TCP anyway so in that sense the transport was always stateful.