HTTP pipelining is a performance optimization that is often overlooked due to its low adoption rate – only the Opera browser uses it by default on desktop .
However, on Mobile HTTP pipelining has a much higher adoption rate – at least the Android and Opera browsers employ it, accounting for about 40% of mobile browsing! In this post we’ll explain what is pipelining, how is it used by the browsers, and what you as a web developer should do about it.
HTTP pipelining has been around for quite a while – since HTTP/1.1 was introduced. When using pipelining, an HTTP client may send multiple requests on the same connection, without waiting for the server to respond. Doing so practically eliminates the round-trip time (RTT) overhead of all but the first request, especially if the server responds quickly.
HTTP pipelining can certainly accelerate many websites, as recently demonstrated by Brian Pane. Unfortunately, due to various issues and challenges most major desktop browsers chose not to support HTTP pipelining (or not to enable it by default). Only Firefox and Opera support it, and only Opera enables it by default – less than 2% of total desktop browsing.
In Mobile, HTTP pipelining is an especially interesting opportunity for two reasons:
- Mobile networks have a much higher latency on average.
This makes the value of avoiding extra RTTs greater
Mobile browsers and websites are newer
As such they tend to get more attention and be more innovative.
And indeed, HTTP pipelining has a much higher adoption amongst mobile browsers. Opera Mini*, Opera Mobile and the Android browser all use HTTP pipelining by default. Together they account for about 40% of mobile browsing. If you’re developing a mobile site, your site is experiencing HTTP pipelining daily, and you should understand how it works.
* Opera Mini uses a proxy to make most requests to the server, and the proxy uses pipelining to make those requests.
The bottom line
Before we dive into details, here’s the final list of HTTP pipelining support. The different columns are explained in the following sections.
|Windows Desktop Browsers||Supports Pipelining?||Server Support Detection||Max pipelined requests||Max connections per host|
|Opera 11.5||Yes||Per Host||5||6|
|Firefox 5||Yes (Off by default)||Per Connection||4||6|
* Logged as an enhancement request since March, 2009
|Mobile Browsers||Supports Pipelining?||Server Support Detection||Max pipelined requests||Max connections per host|
|Opera Mobile||Yes||Per Host||11||4|
|Opera Mini||Yes**||Per Host||4**||10**|
* Details are for “stock” Android. Specific devices varied greatly.
** The stats are for the Opera Mini proxy, as the browser makes very few requests itself
Server Support Detection
The browsers who chose to support HTTP pipelining use heuristics to determine whether the server they’re communicating with supports it as well. The first request to every server is sent by itself (only one request on the connection), and the browser looks for two properties in the response:
- Use of HTTP/1.1
- An explicit “Connection: Keep-Alive” header (required by Android)
If those are not present, requests will be sent without HTTP pipelining. This validation is done per host for Opera Mini, Opera Mobile and Opera Desktop, and per connection for Android and Firefox.
Support per connection means the first request on a connection is always sent by itself (no pipelining). If the response showed the server supports pipelining, multiple requests may be pipelined on that connection.
Figure 1 shows a network capture of Android Pipelining Connection on www.amazon.com. Note the first request “validates” the connection, followed by piped requests.
Support per host means that once the first request showed the server supports pipelining, all future connections will use pipelining immediately. Opera Mini, Opera Mobile and Opera Desktop all use this approach.
Recovery On “Connection: Close”
When using pipelining, the server may always close the connection before all requests are fulfilled. For example, if requests 1 and 2 are sent on the same connection, the response to request 1 may include a “Connection: close” header. In this case, the browser will honor the close instruction and close the connection, without a response to request 2, and resent request two on a different connection.
It’s worth noting that getting such a “Connection: Close” will not make Opera stop using pipelining on that host, even if all future requests come back with such a “close” header.
Max Pipeline Requests
Since pipelining creates a queue of requests, browsers set a limit on how big the queue can get. This helps mitigate the risk of many requests getting delayed by one slow response (dubbed “head-of-line blocking”). All the browsers we tested preferred opening a new connection to pipelining (until reaching their max connections limit). Additional requests will then be piped on existing connections, until all connections reach their max. Remaining requests will wait in the queue.
The algorithms browsers use for distributing pipelined requests will be covered in a subsequent post.
Android Varies Greatly by Device
Android’s versatility made it very hard to predict whether and how pipelining is used. All the devices that supported pipelining maintained the same logic for determining Server Support, but the number of connections and max pipelined requests were very different. Even pipelining support in general wasn’t constant.
|Android Device||OS Version||Supports Pipelining?||Max Connections Per Host||Max Connections||Max pipelined requests|
The Nexus S and the simulator likely indicate the way Android was meant to behave. However, Motorola opted to modify the XOOM, adding many connections and disabling HTTP pipelining. Samsung took the opposite direction, and while they also increased the number of connections, they doubled the number of pipelined requests. Figure 3 shows Samsung Galaxy S piping 6 requests at once.
It’s hard to say which values would be ideal, but the variability in Android definitely makes it hard for website owners to optimize for the entire platform. This may be the result of the different hardware specs being tuned for different settings, or just a symptom of the experimentation phase Android seems to be in. We hope that eventually a more consistent behavior will surface.
Seeing as Google is likely the biggest promoter of making the web faster, it’ll be great if they shared the research that made them choose the initial numbers. Doing so may help convince the manufacturers to stick to it, and will help website owners to optimize accordingly. After all, it’ll probably take some time before most of the web switches to SPDY.
I’m A Mobile Website Developer – What does this mean for me?
If you have a mobile website, HTTP pipelining is a part of your reality – whether you like it or not. You should make sure you support it, and try to tap into the performance opportunity it presents.
Here are some specific recommendations:
- Make sure your web infrastructure supports HTTP pipelining.
If it’s not extremely old, it probably does.
- Use “Connection: Keep-Alive” to leverage pipelining.
Make sure to include an explicit “Connection: Keep-Alive” header for Android.
- Serve slow (dynamic) resources from a different domain than fast (static) ones.
With pipelining, multiple requests may get delayed by one slow response.
- Use Domain Sharding carefully (or not at all) for browsers that support pipelining
Opening more connections is more costly than pipelining (especially on Mobile), and Android relies on pipelining so much it opens very few connections.
- Test your site.
For desktop, download and run Opera and enable Firefox pipelining.
For mobile, tools like http://blaze.io/mobile/, simulators and more can help.