CocoaSPDY: SPDY for iOS / OS X

For over a year now, Twitter has supported the SPDY protocol and today it accounts for a significant percentage of our web traffic. SPDY aims to improve upon a number of HTTP’s shortcomings and one client segment in particular that has a lot of potential to benefit is mobile devices. Cellular networks still suffer from high latency, so reducing client-server roundtrips can have a pronounced impact on a user’s experience.

Up until now, the primary clients that supported SPDY were browsers, led by Chrome and Firefox. Today we’re happy to announce that in addition to rolling out SPDY to our iOS app users around the world, we’re also open sourcing a SPDY framework, CocoaSPDY, for iOS and OS X apps under the permissive Apache 2.0 license. The code is written in Objective-C against the CoreFoundation and Cocoa/Cocoa Touch interfaces and has no external dependencies.

What exactly is SPDY?

SPDY was originally designed at Google as an experimental successor to HTTP. It’s a binary protocol (rather than human-readable like HTTP), but is fully compatible with HTTP. In fact, current draft work on HTTP/2.0 is largely based on the SPDY protocol and its real-world success. At Twitter, we have been participating with other companies in the evolution of the specification and adopting SPDY across our technology stack. We’ve also contributed implementations to open source projects such as Netty. For more details about SPDY, we encourage you to read the whitepaper and the latest specification.

Enabling SPDY

One of our primary goals with our SPDY implementation was to make integration with an existing application as easy, transparent, and seamless as possible. With that in mind, we created two integration mechanisms—one for NSURLConnection and one for NSURLSession—each of which could begin handling an application’s HTTP calls with as little as a one-line change to the code.

While we’ve since added further options for customized behavior and configuration to the interface, it’s still possible to enable SPDY in an iOS or OS X application with a diff as minimal as this:

+[SPDYURLConnectionProtocol registerOrigin:@"https://api.twitter.com:443"];

The simplicity of this integration is in part thanks to Apple’s own well-designed NSURLProtocol interface.

Performance Improvements

We’re still actively experimenting with and tuning our SPDY implementation in order to improve the user’s experience in our app as much as possible. However, we have measured as much as a 30% decrease in latency in the wild for API requests carried over SPDY relative to those carried over HTTP. 

In particular, we’ve observed SPDY helping more as a user’s network conditions get worseThis can be seen in the long tail of the following charts tracking a sample of cellular API traffic:

The x-axis is divided into the 50th percentile (median), 75th, 95th and 99th percentiles of HTTP and SPDY requests. The y-axis represents the raw, unadjusted request latency in milliseconds. Note that latency is a fairly coarse metric that can’t fully demonstrate the benefits of SPDY.

Future Work and Getting Involved

CocoaSPDY is young project under active development, we welcome feedback and contributions. If you’re interested in getting involved outside of usage, some of our future plans include:

Feature requests or bugs should be reported on the GitHub issue tracker.

Acknowledgements

The CocoaSPDY library and framework was originally authored by Michael Schore (@goaway) and Jeff Pinner (@jpinner) and draws significantly from the Netty implementation. Testing and deploying the protocol has been an ongoing collaboration between Twitter’s TFE and iOS Platform teams, with many individuals contributing to its success. We would also like to extend a special thanks to Steve Algernon (@salgernon) at Apple, for providing his insight and assistance with some of the nuances of the Cocoa networking stack.