a persistent connection
Imagine phoning a shop, asking one question, hanging up, then dialling again for the next question, and again for the one after that. The redialling wastes more time than the questions. Early HTTP worked like this: every single file on a page — the HTML, each image, each script — opened a fresh TCP connection, used it once, and closed it. A persistent connection fixes this by keeping the line open and reusing it for many requests in a row.
The cost being saved is the TCP setup. Opening a TCP connection needs a three-way handshake (SYN, SYN-ACK, ACK), which takes one full round trip before any data can flow — and on a far-away server that round trip might be 100 milliseconds. A typical web page pulls in dozens of resources. Non-persistent HTTP pays that handshake (and TCP's slow-start ramp-up) once per resource; persistent HTTP pays it once, then sends request after request over the same warm connection. HTTP/1.1 made persistent connections the default, with a "Connection: keep-alive" understanding, and the server keeps the socket open until it has been idle for a while.
A related idea is pipelining: sending several requests back-to-back without waiting for each response first, to fill the pipe. In practice HTTP/1.1 pipelining was rarely used, because responses had to come back in the same order they were requested — so one slow response stalled everything behind it (head-of-line blocking). That unsolved limitation is precisely what HTTP/2's multiplexing and then HTTP/3 were designed to overcome. So a persistent connection removes the per-request handshake but, in HTTP/1.1, still serialises the responses.
A page needs the HTML plus 30 images, all from one server 100 ms away. Non-persistent: roughly 31 handshakes, each costing a round trip up front. Persistent: one handshake, then all 31 requests flow over the warm connection — saving roughly 3 seconds of pure waiting before anything even downloads.
Reusing one warm TCP connection avoids paying the handshake round trip over and over.
Persistent connections in HTTP/1.1 do not let responses overtake one another — they are still delivered in request order on that one connection. Solving that required HTTP/2's multiplexing; do not confuse keep-alive with true parallelism.