Keep-Alive (persistent connection) reuses a single TCP connection for multiple HTTP request/response exchanges, eliminating the cost of opening and closing a connection per request.
Persistent connections are the default from HTTP/1.1 onward, avoiding repeated TCP/TLS handshakes and greatly reducing latency.
In HTTP/1.0, each request opened a new connection and closed it after the response, so a page with dozens of images, CSS, and JS files incurred that many 3-way handshakes (plus TLS) — a huge overhead. Keep-Alive amortizes this by keeping the connection open and streaming multiple requests through it. It's controlled by the `Connection: keep-alive` header along with idle timeouts and a max-request count.
However, HTTP/1.1 persistent connections process requests only serially on a connection (you must receive a response before sending the next; pipelining is effectively unused). So a slow earlier response blocks later ones — application-layer Head-of-Line blocking — which is why browsers open around six parallel connections per origin to work around it. HTTP/2's multiplexing fundamentally solves this by handling many streams concurrently over one connection.