The Hypertext Transfer Protocol (HTTP) is the foundation of data communication on the web. Although HTTP/1.1 has been a standard since 1997, many web developers don’t fully utilize its advanced features for optimized performance. In this post, I’ll explain some key capabilities in HTTP 1.1 and how to leverage them.
Performance issues from Non-persistent connection?
In the early days of HTTP, each request would open a new TCP connection, introduce handshake delays, and accumulate TIME_WAIT sockets after closing.
HTTP 1.1 introduced persistent connections through the Connection header with “keep-alive” value. This allows multiple requests/responses to reuse one TCP connection:
- Avoiding TCP handshake overhead
- Preventing port exhaustion via too many TIME_WAIT sockets
- Enabling request pipelining
How to segment messages in a persistent connection?
Before HTTP 1.1, each request had to wait for the prior response before being sent. This led to significant delays and underutilization of the TCP connection.
Pipelining allows the client to make multiple requests over a single connection without waiting for each response. This results in much better utilization of available network bandwidth.
Calculating the Content-Length header before sending response data introduces delays in first byte delivery. Chunked transfer encoding was introduced to avoid this.
With chunked encoding, the server can begin sending data before knowing the total length. The body is sent in “chunks” with their own length:
This allows response streaming without a pre-calculated content length.
Caching improves performance by reducing redundant requests. HTTP 1.1 has rich caching capabilities through ETags, Cache-Control, and Conditional Requests.
ETags uniquely identify versions of resources. Cache-Control headers tell proxies how to cache responses. Conditional GETs with If-None-Match headers check the ETag to validate caches.
This enables robust caching of both static and dynamically generated content:
HTTP 1.1 provides big performance wins over earlier versions through persistent connections, pipelining, chunked transfer encoding, and caching. Modern web developers should understand these features to optimize web and API performance.
Let me know if you would like me to expand or modify anything in this initial draft! I’m happy to revise it based on your feedback.