HTTP/1.1, HTTP/2 & HTTP/3
Requests, responses, headers and status codes; then the evolution from HTTP/1.1 through HTTP/2 multiplexing to HTTP/3 over QUIC; keep-alive and connection pooling.
HTTP turns a byte stream into a request — method, path, headers, optional body — and a response — status code, headers, optional body; the method tells intermediaries whether a request is safe to retry and the status code tells the client what to do next.
A `fetch()` becomes an HTTP message inside TLS records inside TCP segments inside IP packets, crosses the network, is unwrapped in reverse on the server, handled, and returns the same way — and on a cold connection most of the time is round trips, not work.
HTTP/1.1 keeps the TCP connection open between requests and delimits bodies with `Content-Length` or chunks, but it can only carry one response at a time per connection — so browsers open several connections per origin, and text parsing costs bytes and ambiguity on every message.
HTTP/2 replaces text lines with binary frames tagged by stream id, so many requests and responses interleave on a single TCP connection with compressed headers — at the cost that one lost TCP segment now stalls every stream on that connection.
HTTP/3 runs over QUIC, a UDP-based transport that folds TLS 1.3 into its handshake, gives each stream independent loss recovery, and survives a change of IP address — reducing, not eliminating, head-of-line blocking, at the price of userspace CPU and UDP-hostile networks.
Three versions with identical semantics and three different transports: sequential text over TCP, multiplexed frames over one TCP connection, and multiplexed streams over QUIC — each is the right choice for a different link and a different deployment.
Reusing a connection skips the TCP and TLS handshakes and starts with a grown congestion window — but both ends, and every proxy between them, close idle connections on their own timers, and the race between a server closing and a client reusing produces the sporadic `ECONNRESET` every production system eventually meets.
Opening a connection costs handshakes, authentication and a cold congestion window, so clients keep a pool of open ones and hand them out per request — HTTP pools hold stateless connections any request can use, database pools hold connections that carry session state, and both fail the same way when the pool runs dry.