In HTTP/1.1, what does it mean that connections are persistent by default, and what effect does sending the HTTP header `Connection: close` have on a request or response?
answer
- 1.1 persistent by default, 1.0 closed by default
- No close-to-frame: needs Content-Length or chunked
- Connection: close = last message on this link
- Connection is hop-by-hop, proxies strip it
- keep-alive value is a 1.0 relic / HTTP2 bans it
basics
~20 sHTTP/1.1 leaves the TCP connection open after a response so the next request reuses it instead of paying for a new handshake. Connection: close announces this is the last message on that connection; the sender closes it once the message ends.
solid answer
~50 sIn HTTP/1.0 each request opened a fresh TCP connection and the server closed it to signal the end of the response. HTTP/1.1 inverted the default: the connection is **persistent** unless someone says otherwise, so a client can send request after request on the same socket. That works only because HTTP/1.1 requires explicit message framing (`Content-Length` or `Transfer-Encoding: chunked`), so both sides know exactly where one message ends and the next begins. `Connection: close` is the opt-out. Either side may send it: a client saying "this is my last request here", or a server saying "read this response, then treat the connection as dead". After the message completes the sender closes the socket and the peer must not reuse it. `Connection` is a **hop-by-hop** header: it describes one TCP link, so a proxy consumes it rather than forwarding it. You do not need `Connection: keep-alive` in HTTP/1.1 - it is a leftover from HTTP/1.0, where it was the way to *request* reuse.
code
http · 17 linesGET /a HTTP/1.1
Host: api.example.com
HTTP/1.1 200 OK
Content-Length: 2
ok
GET /b HTTP/1.1
Host: api.example.com
Connection: close
HTTP/1.1 200 OK
Content-Length: 2
Connection: close
okgo deeper
Know the default (persistent in 1.1) and that Connection: close ends the connection after the current message. Being able to state that reuse avoids repeated TCP/TLS handshakes is enough.
Add the framing requirement - Content-Length or chunked - and explain why closing can no longer delimit a response. Mention that Connection: keep-alive is an HTTP/1.0 leftover.
Discuss hop-by-hop semantics through proxies, servers emitting close during draining or after request caps, and the request-smuggling risk when two hops disagree on framing.
Frame it as connection lifecycle policy across a fleet: who terminates TLS, how draining and recycling are coordinated with load balancers, and how the model changes under HTTP/2 or HTTP/3 where GOAWAY replaces close.
## Why persistence exists HTTP runs over TCP. Opening a TCP connection costs a three-way handshake - a full round trip before any HTTP byte moves - and TLS adds one or two more round trips. HTTP/1.0's default was one connection per request/response pair, so a page with thirty images paid thirty handshakes. HTTP/1.1 (RFC 9112) made the connection **persistent by default**: after the response is fully read, both sides keep the socket open and the client may send the next request on it. ## What makes reuse possible: framing If the connection stays open, "the server closed the socket" can no longer mean "the response ended". HTTP/1.1 therefore requires every message to carry explicit length information: - `Content-Length: 1234` - read exactly that many bytes of body; or - `Transfer-Encoding: chunked` - a series of size-prefixed chunks ending with a zero-length chunk; or - no body at all (204, 304, responses to HEAD). A response with none of these can only be delimited by closing the connection, which forces `Connection: close`. This is also why sloppy framing is a security problem: if a front-end proxy and a back-end server disagree about where a message ends on a shared reused connection, an attacker can smuggle a second request into the stream. ## Connection: close `Connection: close` is a declaration about the *current* connection, not an error. Typical senders: - a client that knows it has one request to make (`curl` without further requests, a health checker); - a server that is shutting down, recycling the connection after a request cap, or replying to an HTTP/1.0 client; - a server that cannot frame the response deterministically. Semantics: the sender finishes the in-flight message, then closes. The receiver must not send anything further on that connection; a well-behaved client transparently opens a new connection for its next request, so `close` is invisible to application code. ## Hop-by-hop, not end-to-end `Connection` is hop-by-hop. It applies to the single TCP link between two adjacent parties (client-to-proxy, proxy-to-server). A proxy must remove it - along with any header it names - before forwarding. So a browser that sends `Connection: close` closes only its link to the CDN edge; the edge's pooled connection to the origin is unaffected. Failing to strip hop-by-hop headers is a classic proxy bug. ## HTTP/1.0 interop and the keep-alive header Under HTTP/1.0 the default was to close, and reuse was requested with the non-standard `Connection: keep-alive`. Many servers still echo an informational `Keep-Alive: timeout=5, max=100` header, which hints how long the connection stays idle before the server drops it and how many requests it will serve. In HTTP/1.1 sending `Connection: keep-alive` is redundant; its presence in a codebase usually signals someone cargo-culted 1.0 behaviour. ## Later versions HTTP/2 and HTTP/3 go further: a single connection per origin carries many concurrent streams, and `Connection` (plus other hop-by-hop headers) is forbidden entirely - orderly shutdown is signalled with a GOAWAY frame instead. The mental model stays the same: connections are expensive, so protocols work hard to keep and reuse one.
- On a reused connection, how does the client know where one response ends and the next begins?From explicit framing in the response: a Content-Length header giving the exact body size, or Transfer-Encoding: chunked, where each chunk is prefixed by its size in hex and a zero-size chunk terminates the body. Status codes 204 and 304, and responses to HEAD, have no body at all. If a response has none of these, the only delimiter left is closing the connection, so the server must also send Connection: close.
- Is Connection an end-to-end or a hop-by-hop header, and why does that matter through a proxy?It is hop-by-hop: it describes the single TCP link between two adjacent parties. A proxy must consume it and not forward it, and must also strip any header listed in its value. So a client sending Connection: close only ends its own link to the proxy; the proxy's pooled connection to the origin keeps living. A proxy that forwards Connection verbatim will tear down upstream pools unnecessarily.
A phone call you keep open for a series of questions instead of hanging up and redialling after each one. Connection: close is "this is my last question, I'll hang up after your answer".
saying these in an interview costs you the question
- Saying you must send `Connection: keep-alive` in HTTP/1.1 for reuse - it is the default
- Thinking keep-alive means the server can push data to the client unprompted
- Claiming persistent connections let multiple requests be in flight at once in HTTP/1.1 - responses are still returned strictly in order
- Treating `Connection: close` as an error or a failure signal rather than a normal lifecycle message
- Believing a proxy forwards the Connection header end-to-end