A10‘s presentation at NFD8 seemed to generate a bit of interest (dare I say excitement) and many a question around the SPDY (pronounced ‘speedy’) protocol. I promised Lindsey Hill (@northlandboy) on Twitter that I’d write a blog post about it and here it is. It took me rather longer to write than I thought and I suspect a few follow-up posts might be in order, we’ll see.
So, what the heck is SPDY? Why was it created? Should you care? How does it work? I’ll answer at least the first three questions in this post, as well as provide some detail around web browser, server and load balancer support. Just for some context I’ll also cover some performance related features that were introduced with the current HTTP version: 1.1.
So, what is it? It’s not a new version, replacement or even enhancement of HTTP as some might think, rather, it’s an entirely compatible, yet independent protocol that was and continues to be designed (by Google) to improve HTTP performance. SPDY Does form the basis of the new HTTP/2.0 protocol standard due
later this early next year (2015) and HTTP/2.0 will effectively be SPDY/4 but don’t expect the two to be remain compatible after this confluence. As great as that would be, it’s better that SPDY evolves at a fast pace to meet current needs than is held back by a glacial standards body. Still, considering the work that has gone into HTTP/2.0 perhaps there will no longer be a need for another version of SPDY.
The WebSocket protocol is similar in many ways but has no HTTP headers and thus far less compatibility with existing systems.
You can find the Google SPDY website here: http://www.chromium.org/spdy/ and protocol ‘drafts’ here: http://dev.chromium.org/spdy/spdy-protocol/. The HTTP/2.0 specification draft can be found here: https://github.com/http2/http2-spec.
Two things, first, the HTTP/1.1 standard is almost 15 years old and much has changed and secondly, there’s plenty of room for performance improvements.
I think we can thank SPDY for prompting (or at least accelerating) creation of the HTTP/2.0 standard that’s near release, not a minute too soon I’m sure most in this space agree.
Performance itself matters greatly for nearly all websites; its well understood that better performance provides both direct and indirect benefits around customer satisfaction, retention, purchase conversion, application usage, stickiness and more.
I’ve seen various statistics stating SPDY increases performance by up to 50% but that’s not a figure I’d be happy to supply. As ever, the real answer is “it depends”; a number of factors influence the gains that might be had, from the number and size of HTTP headers to the latency and quality of the network between the client and server. More on this later but suffice to say that I think most would see a worthwhile increase in performance and corresponding reduction in concurrent TCP connections (and bandwidth usage).
I’ve not mentioned security till now. Considering the post-Snowden world we live in today I really don’t see SPDY’s current requirement to use SSL/TLS as significant but you could certainly say it was far-sighted.
Before we dive into the details of SPDY I though it would be worthwhile explaining how HTTP/1.1 improved on HTTP/1.0 all those years ago.
HTTP/1.1 Performance Improvements
Note: I have ignored the possibility of responses being larger than one packet and have simplified other matters around timing so please keep in mind things might take a little longer than I’ve stated in practise, but not by much.
Here’s how HTTP/1.0 worked. If the packet Round Trip Time (RTT) is 30ms, it’ll take 7.2 seconds to make three requests and receive the relevant responses (I’ve only shown two below for brevity). Even if we ignore the connection closures we’d still be looking at 4.5 seconds. DNS lookups will of course potentially add more delay. SSL/TLS considerably more. Considering the average web page typically requires 100’s of requests this simply isn’t usable any more.
Pretty inefficient, so HTTP/1.1 introduced Persistent Connections. Using the same RTT as before, we can make the same three requests and get the responses in 3.9 seconds or 2.7 seconds if we ignore the connection closure. That’s almost half the time HTTP/1.0 would have taken. The more requests we make the greater the benefit.
That then allows for Pipelining, although proxies often break this and a fair few browsers don’t have this feature enabled. Note that responses must be sent in the order they were received, which can still result in delays and head of line blocking. Ignoring that for now, we can make three requests and get the responses in 2.7 seconds, 1.5 seconds if we ignore connection closure. That’s almost half of the Persistent Connections figure and a third of the HTTP/1.0 one. Again, the more requests we make the greater the benefit.
Concurrent TCP connections can also help and this is widely used. If we make four requests over two connections and use Pipelining on each we can make those requests and get the responses in 2.4 seconds, 1.5 seconds ignoring connection closures. Another four requests only adds 0.6 seconds. Of course, we could make all eight requests at once and not add any additional delay at all but there are practical limits and note my earlier comments about Pipelining breaking things. All in all, pretty good but considering the size of modern-day web pages, not good enough in many cases. Also note that more connections means a greater load (and memory usage) on any stateful device in path (firewalls, load balancers, servers etc.)
As I stated before, DNS lookups will of course potentially add more delay and SSL/TLS considerably more, initially at least.
Compression (body data only), caching, proxies, CDNs and other HTTP features can also help improve performance further.
Additionally, improvements are also possible at the TCP and IP layers (disabling Slow Start for instance) but these often rely on a good understanding (and ideally control) of your client base.
There is some debate over which OSI model layers both SPDY and SSL/TLS (which it required) operate at so I think it would be best simply to say SPDY operates above SSL/TLS and below HTTP (so, between the two). I’ll leave the debate to the pedants. Version numbers relate to the draft specification version; the current complete one being 3.1.
SPDY improves performance with HTTP/1.1 in many ways (whilst not using Pipelining or concurrent connections);
- True request multiplexing (effectively parallel processing over a single TCP connection although in theory its still sent serially on the wire); there are no limits or requirements around response order and thus no head of line blocking or delays. Multiple ‘sessions’ within the single TCP connection are called streams. This avoids the need for multiple concurrent connections which provides huge benefits to clients, servers, firewalls and everything in between. However, note that TCP Slow Start reduces performance initially.
SPDY Can be compared in some ways to TCP in the way it operates around streams and is often called TCP over/for HTTP (over TCP again of course). SPDY Stream operation uses RST_STREAM, SYN_STREAM, SYN_REPLY, PING and WINDOW_UPDATE ‘frames’ (which are binary by the way) amongst others, allowing it to provide TCP-like transport functions. This may seem like pointless duplication but lets just remember its essentially operating at the application layer where it becomes far more useful and can be easily exposed to and controlled by software. Its more sophisticated and potentially more intelligent.
Also note using multiple concurrent connections already subverts some TCP operations. It does in some senses ignore the underlying network and recent advances in the industry I’d agree and perhaps that may make some of its features less attractive in the future but for now its all good. Ever more complex HTTP applications will hopefully take full advantage.
- Response prioritisation at the client’s request; more specifically, one or more streams are prioritised. How this QoS-like prioritisation is implemented is dependent on the server configuration.
- HTTP Headers (which can be considerable in some cases and which are mostly duplicated with each request and response) are compressed in addition to the body data. There is still some data that isn’t compressed but its marginal (always less than 20Bytes and often less than 10B in many cases). In my experience compression should reduce header size by around 70-80% which is significant considering a typically User-Agent header value is 100B or more these days and even a URL can easily be that size. Details on the new HPACK compression can be found here: https://github.com/http2/http2-spec/blob/master/draft-ietf-httpbis-header-compression.xml. This new compression scheme, replacing zlib, overcomes the security risks associated with compression and SSL CRIME and BEAST attacks.
Unfortunately I can’t think of a useful way to represent and demonstrate the benefit of all these features visually but I think its pretty clear with at least three of the features detailed above that significant performance gains are possible. However, to balance this, don’t forget that you’ll no longer be benefiting from HTTP/1.1 Pipelining or the use of concurrent connections. SPDY Wins out as far as I’m concerned and, as demonstrated by the list of websites using SPDY detailed later, so do some very large web-scale companies. There are many factors involved so as always, do your own testing to make your case.
A draft of v4 is available and is particularly interesting as it supports server push of DNS records and certificates. This will seriously take performance to the next level in many cases.
There’s always a trade off. So, what’s the cost of these improvements;
- Many of today’s ‘hacks’ for improving page load times (sharding, inlining etc.) are no longer required and may actually reduce performance with SPDY. These sites need to re-code to take advantage of SPDYs benefits. This should be worthwhile considering it allows for simplification.
- Headers are now binary and thus impossible to read/understand without using software that can do the necessary conversion to something human-readable.
- HPACK Compressed headers are ‘stateful’ and this will make troubleshooting extremely difficult as the full state is only fully known by the client and server. I’m sure this will be overcome but I still expect packet capture and analysis tools will need to see the whole ‘session’ to be useful. We may be forced to View HTTP Headers Using Browser Developer Tools.
- Long lived connections present potential security and privacy/tracking risks.
- Most implementations require use of TLS. The benefits of TLS Everywhere are highly contentious. Troubleshooting also becomes very hard; we may be forced to View HTTP Headers Using Browser Developer Tools once again.
Other Things to Note
Just in case it not obvious, mobile users will probably benefit the most.
SPDY Headers are all prefixed with : to ensure there is no possible clash with HTTP headers.
SPDY and NTLM are incompatible.
It’s recommended you leave SPDY connections open for as long as possible to reduce TCP three-way handshake overheads.
Prior concerns around SPDY security have been mostly resolved. Note however that HTTP compression still currently represents a security risk even when SSL/TLS is used, whether using SPDY or not.
Note as far as I’m aware all implementations require the use of TLS.
- Chrome (Chromium) – from v29
- Chrome for Android – from v37
- Firefox – SPDY/2 from v11 (disabled by default), default enabled from v13, support dropped in v28, SPDY/3 from v15 and SPDY/3.1 from v27
- Internet Explorer – from v11 on Windows 8
- Opera – from v23
- Safari – from v8
- Silk – from day one (to/from Amazon systems only)
SPDY Modules are available for the follow web servers;
- Apache – from v2.2
- Nginx – SPDY/2 prior to v1.5.10 and SPDY/3.1 from v1.5.10
- OpenLiteSpeed – SPDY/2, SPDY/3 from v1.1 and SPDY/3.1 from v1.2.
Notable exceptions are Microsoft IIS and LightHTTPd.
Load Balancer Support
In all cases early feature support is limited and improves in later versions;
- F5 Networks TMOS from v11.2, SPDY/3.1 support from v11.6
- Citrix Netscaler supports SPDY/2 from v10.1 and /3 from v10.5
- A10 supports SPDY/3.0 on Thunder ADC from v2.7.1
The Firefox SPDY indicator Add-on displays an indicator showing SPDY support in the address bar: https://addons.mozilla.org/En-us/firefox/addon/spdy-indicator/.
The SPDYCheck site checks if a website support SPDY and provides detailed information on its implementation.
Websites/Services Using SPDY
Facebook, Twitter, Cloudflare, WordPress and most Google sites and services,
If this is a subject that interests you, I’d highly recommend you read the free High Performance Browser Networking book by Ilya Grigorik available here: http://chimera.labs.oreilly.com/books/1230000000545.
SPDY Based Protocols
Microsoft’s Speed and Mobility protocol is a revision of SPDY. More information can be found here: http://en.wikipedia.org/wiki/Microsoft_SM and here: http://tools.ietf.org/html/draft-montenegro-httpbis-speed-mobility-01.
HTTP/2.0 (aka HTTPbis) uses an early version of SPDY as its starting point. More information can be found here: http://en.wikipedia.org/wiki/HTTP/2 and here: https://datatracker.ietf.org/wg/httpbis/charter/.
If you like to see just how large some headers can get, this might help you: https://packetpushers.net/viewing-http-headers-using-browser-tools/.