The Chromium team at Google has announced SPDY, an experimental new application-level message framing protocol for the web. SPDY is designed to speed up web browsing by reducing latency and minimizing the effect of lossy and slow networks. I worked for a time on the WAAS WAN Optimization product at Cisco, and was particularly interested in optimizations to HTTP, so I'm glad to see Google making an effort to work on this problem.
The SPDY whitepaper has a good overview of the current understanding of the performance issues in HTTP. I'll try to illustrate those problems, and explain how SPDY proposes to address them.
In theory, a web browser simply opens a connection to a server, requests a page, and receives the page's data. In practice, of course, most web pages are made of many objects, most of which need to be retrieved for the page to be rendered correctly. All modern browsers open multiple TCP connections to retrieve these objects, and interleave the requests for the objects across all the TCP streams, like this:
(In these diagrams, each grey box indicates a single data stream; the blue portion is when we are sending or receiving data. The length of each blue portion is a function of the client send time, the time for the packet to reach the server, the time for the server to process the request, and the time for all of the packets of the response to reach the client. The exact length of the response time is therefore a function of the network latency and the TCP window size, which is more detail than I'm going to go into now!)
I'm illustrating a couple points with this diagram:
- The client can't start requesting objects until it finishes receiving the first page. That's because the web browser needs to parse the HTML to discover the addresses of all the embedded objects. (Some browsers now start requesting embedded objects before they finish parsing the page, which means that the very first blue bar doesn't need to be done before the new black bars start).
- Some requests are handled very quickly, while others take more time -- the fastest hits are due to a cache hit, when the server simply returns an Unmodified header. The client has no way of knowing which request is going to be a fast one when it makes it though (though it could try to guess). That's too bad, because the client can actually make a pretty good guess about which requests are the important ones (prioritizing, say, the big image right in front of the user, instead of the image in the footer that is scrolled off the screen right now). In practice, HTTP has the head of line blocking problem.
- The transmission time includes the time to send both the message headers and the message body. For small messages, the message headers are much larger than the body -- in a cache hit case, the message is 100% headers.
- More TCP streams leads directly to lower latency. Most modern web browsers open six connections to a server, which reduces perceived latency significantly. But those streams are not free: they consume flow records in a load balancer, a file descriptor in the web server's operating system, and (in most server implementations) a thread or process in the web server.
Now, in a real-world network, the story gets a bit uglier. Here's a diagram that shows what happens in a high-packet-loss network:
In these diagrams, the red region shows where a packet was lost. Under TCP retransmission rules, the entire stream is stalled while the sending party waits for the ACK, decides that packet loss has occured, and retransmits. In practice, this can take a second or more.
The picture gets even uglier if the packet loss occurs early in the flow:
In this picture, a packet was lost during the initial page request (or even, worst case, during the initial SYN of the TCP handshake). In that case, the entire page load is stalled waiting for that one stream to retransmit.
How SPDY Changes The Picture
SPDY proposes to keep the TCP substrate of HTTP, and to preserve the request/response message exchange format, but to replace the stream-oriented protocol with a more sophisticated multiplexed message framing protocol. It looks like this:
- The client opens a single TCP connection to the server, and sends HTTP requests down it.
- Requests and responses can be multiplexed on this single connection.
- Headers are compressed (notice that the cached message pairs are much shorter).
- The server has the option of initiating "server push", by delivering some responses that the client did not ask for, because it knows they will be needed.
- Individual bars take a bit longer, because the available bandwidth is shared.
In the best case, SPDY can be much faster than HTTP-over-multiple-TCP.
The SPDY designers mandated that it must run over SSL. While they claim that this is for the security benefit, I think it far more likely that it is because it allowed them to tunnel through application-aware networking infrastructure.
Alternative Approaches
The Stream Control Transmission Protocol attacks the problem at the transport layer. SCTP proposes to replace TCP, a single-connection, stream-oriented protocol, with an association-based, multi-stream protocol, still running over IP.
There is an Internet Society paper, "Why is SCTP needed given TCP and UDP are widely available?", which does a good job explaining the advantages of SCTP. Some experimental work on supporting HTTP over SCTP has been done, and a prototype of HTTP-over-SCTP in Firefox has been demonstrated.
SCTP has been around for almost ten years, and hasn't really seen much uptake, despite having many attractive characteristics. It would require updates to many pieces of the computing infrastructure, both in application-aware networking gear (load balancers, firewalls, etc.) and in client and server operating systems and applications.
So, what next?
It looks like the Google team has done some great work, and has tried hard to strike a balance between progress and compatibility. Like all attempts to improve the infrastructure of a system that is under heavy use, there are a lot of hard questions to ask about it.
- The SPDY research (and other work done by other teams) has shown that HTTP header compression has major benefits, especially on low-bandwidth uplinks. I'd be interested in analyzing the speedup of just adding header compression to HTTP/1.1.
- Tunneling over SSL allows SPDY to hide from large chunks of the application-aware network infrastructure, but there is still a huge deployed base of SSL-terminating load balancers and reverse proxies. Upgrading every data center in the world to work with SPDY would be a huge task -- I'd like to see more thinking about how we could gracefully upgrade the world.
- The server push model proposed by SPDY raises some interesting possibilities for server-side optimization of perceived client latency. I can imagine a "site compiler" that builds a resource manifest for each page and prepositions the content -- the problem, of course, is that a cache hit beats a server push every time. Perhaps the server should push an object manifest to the client, which would allow the client to make a single request for all the objects that it doesn't have cached yet.