Keep-alive (persistent) connections with Java Servlets

If you are using a Servlet to serve frequently-accessed content, then you may need to concern yourself with the issue of keep-alive connections (also called persistent connections). In the very early days of HTTP, it was common for every single request to involve opening and closing a new connection. For example, to display a page with 9 images, this would involve a sequence of 10 separate connections to the server. Since HTTP 1.1, the default behaviour has been for connections to be kept open or "alive" between requests.

In order for a single connection to serve multiple requests, a little bit of trickery is necessary within the HTTP protocol, because we can't just mark the end of the data by closing the connection. The most common solution is that before every response (i.e. page, image etc) returned, a Content-Length header is inserted which gives the length in bytes of the following data. This is easy for the web server if it's serving a static page such as an HTML file. But it's more difficult with dynamic content generated, for example, by a PHP script or Java Servlet. From the perspective of a Java Servlet, there are essentially two solutions.

The first solution is to rely on buffering by the web server itself. In other words, we return output from our Servlet as normal, and hope that the server (Apache, IIS etc) will automatically be buffering our output in order to count its length and insert a Content-Length header1. Some web servers do appear to do this. If you can determine that your web server is indeed buffering, then life is a bit easier. Below, we'll see a simple way to determine if the web server is buffering your Servlet output.

The second solution is to manually set a Content-Length header within the Servlet itself. To do this, we need to be able to predict the length of the output we're going to send. Or in the worst case, buffer it ourselves in order to measure the length before sending it.

Does my web server buffer Servlet output?

A simple way to determine if your web server is buffering the output of your Servlet is to see what it's outputting! If you're feeling fancy, you could do this with a packet sniffer. But a simpler way is to use a humble telnet connection. The procedure is as follows:

If the Content-Length header isn't present, then you probably want to set the Content-Length header within your Servlet.


1. HTTP provides another solution called "chunked encoding", in which the length of the whole content isn't supplied at once, but rather of individual "chunks" or "buffers", and eventually the final one is signalled. As far as I am aware, few servers actually support sending the output from a Servlet as chunked encoding.