I have a (mostly working, neglected) implementation of SPDYv2 in erlang (github.com/RJ/erlang-spdy). I've been following the mailing list about the v3 spec. Notable differences if you are updating a spdy library:
* various fields changed size
* compression dictionary [1] for headers block updated
* a few things clarified where spec was ambiguous
* CREDENTIAL frame, so multiple ssl certs can be used on one connection
* addition of per-stream flow control
The last two are probably the most work for implementers.
Still has a prefix dictionary. The benefit of the prefix dictionary over starting from scratch is extremely marginal (about a hundred bytes on the first request).
Still making claims comparing to HTTP without pipelining. After how long they still haven't even compared to pipelining (because Chrome doesn't do pipelining, is Firefox is banned at Google or something?)
Still has server push. Read the spec at how complicated this is, all to save one one-way trip.
> Still has a prefix dictionary. The benefit of the prefix dictionary over starting from scratch is extremely marginal (about a hundred bytes on the first request).
And when the entire exchange consists of a few hundred bytes (which the server can answer with a 304 Not Modified), that seems like a substantial win. What argument do you have against doing this?
> Still making claims comparing to HTTP without pipelining. After how long they still haven't even compared to pipelining (because Chrome doesn't do pipelining, is Firefox is banned at Google or something?)
Firefox still doesn't do pipelining by default either, with the stated reason that some web servers will break with it enabled. Using HTTP pipelining at this point would require some kind of positive indication from the server that it will work, or some kind of autodetection by the browser (which will take multiple requests to do). Also, HTTP pipelining requires answering requests in order, while SPDY doesn't, allowing the server to respond to requests as data becomes available.
> Still has server push. Read the spec at how complicated this is, all to save one one-way trip.
Server push potentially eliminates several full round trips. If I request a page generated by an expensive CGI, the server can go ahead and send me the CSS and JavaScript it knows all pages will reference, and the pile of images referenced from that CSS or JavaScript, all while the CGI runs. That eliminates at least two round-trips, or even more if more images exist than the maximum number of concurrent requests browsers will hit a server with.
> Still hardcodes parts of HTTP into the protocol.
SPDY specifically exists to replace HTTP, not anything else.
> And when the entire exchange consists of a few hundred bytes (which the server can answer with a 304 Not Modified), that seems like a substantial win. What argument do you have against doing this?
Turn this around. What's the argument for doing it? "The gain using our proposed initial dictionary is seen only for the first header". This is completely counter to the goal of Spdy to keep connections open and reuse them; the longer connections are used the less the initial dictionary matters.
Even just visiting one page, average say 500 KiB, it save on average 121 bytes total. That's 0.02% reduction in size. This seems like a "substantial win"?
Meanwhile how many version of the dictionary are there so far? 5? 10? And they propose that it will evolve over time, so that will just keep growing with software everywhere having dozens of legacy dictionaries.
> Also, HTTP pipelining requires answering requests in order, while SPDY doesn't, allowing the server to respond to requests as data becomes available.
This is why metrics are important. By ignoring pipelining because of perceived problems, the authors are basing their protocol on assumptions. This assumption is that in the real world the 'head of line blocking' is a significant factor. Judging by 0.02% average gain from prefix dictionaries, I don't give them the benefit of the doubt that their assumptions are correct. But I see that Chrome 17 has some type of pipelining support, so maybe they will actually test this someday.
> If I request a page generated by an expensive CGI, the server can go ahead and send me the CSS and JavaScript it knows all pages will reference ...
Yes if the very first request is an expensive CGI this may be some marginal benefit. I think even the Spdy designers claimed this was less than 1% and sometimes a loss. This happens very often, that the first page requested from a site has some really slow loading CGI? I think the site is broken.
> Turn this around. What's the argument for doing it? "The gain using our proposed initial dictionary is seen only for the first header". This is completely counter to the goal of Spdy to keep connections open and reuse them; the longer connections are used the less the initial dictionary matters.
Browsers won't keep SPDY connections open forever in the hopes of someday reusing them; the "initial connection" case will happen quite frequently in a normal browsing session.
> Even just visiting one page, average say 500 KiB, it save on average 121 bytes total. That's 0.02% reduction in size. This seems like a "substantial win"?
When did you last visit a page with 500k of HTML? I suggested the hopefully very common case of sending a very small request and getting back a very small 304. The whole exchange consists entirely of headers; I just checked a few examples and got figures in the 300-400 byte range for request and response combined. That would make 121 bytes closer to a 30-40% savings.
(Also, I'd love to see a reference for your figures on expected bytes saved through the prefix dictionary.)
> Yes if the very first request is an expensive CGI this may be some marginal benefit. I think even the Spdy designers claimed this was less than 1% and sometimes a loss. This happens very often, that the first page requested from a site has some really slow loading CGI? I think the site is broken.
Server push seems like a win at any point in a SPDY connection, not just for the initial connection.
> Browsers won't keep SPDY connections open forever in the hopes of someday reusing them; the "initial connection" case will happen quite frequently in a normal browsing session.
This is what boggles my mind about Spdy, the dissonance. On the one hand Spdy is great because it does a bunch of requests on the same TCP connection, but on the other hand Spdy is great because it saves 100 bytes per connection and that's a big deal because there are going to be so many connections made? It doesn't make sense.
Spdy is great because it has compression, but on the other hand Spdy is great because it requires SSL which already has compression. Huh?
> I suggested the hopefully very common case of sending a very small request and getting back a very small 304. ... The whole exchange consists entirely of headers ... That would make 121 bytes closer to a 30-40% savings.
On a first request only. You visit some site and only check if exactly one resource? Not likely. In any case, the cost to transfer 100 bytes once is irrelevant in any grand scheme of things.
> (Also, I'd love to see a reference for your figures on expected bytes saved through the prefix dictionary.)
The dictionary construction part is suspect though... take a look at how many times the same string length count (\0\0\0\4 for example) occurs in the prefix -- this can't be optimal.
I was under the impression that even though TLS has the idea of built-in compression, in practice, that is never actually used. Otherwise why would browsers include Accept-Encoding headers, and servers include Content-Encoding headers, when they could just negotiate compression via the TLS handshake.
Also, you claim that Google is basing this protocol on assumptions and you imply that they do not understand the value of metrics. I strongly disagree with this sentiment, mostly because Google's propensity for data-driven experimentation once wasted an afternoon of mine.
I once spent an afternoon debugging a SPDY server that wasn't negotiating spdy/2 over NPN properly. Turns out that for 5% of startups Chrome will disable SPDY, fallback to plain HTTPS, and collect anonymized performance metrics. You will, of course, argue that this is not a fair comparison with a pipelined HTTP stack. I have posted before about the issues with pipelining, and won't repeat myself here. Suffice it to say that pipelining has many problems; problems of a large enough magnitude that it might be easier for a browser to implement a new protocol than it would be to (correctly) apply the many heuristics necessary to enable pipelining in the wild. SPDY would also cause requests and responses to conform to an asynchronous model, which (to me) is wildly preferable to the synchronous one prescribed by HTTP pipelining (and HTTP in general).
(edit)
And to answer your question about why \0\0\0\4 and other lengths appears so many times in the newest version of the prefix dictionary (the 2nd one AFAIK), its because SPDY headers are length-prefixed for ease of parsing. It compresses better when the prefix is included in the dictionary; such that {0x00,0x00,0x00,0x07,o,p,t,i,o,n,s,} would compress to one byte, not 5 (assuming that that entry was still in the dictionary of course).
> I was under the impression that even though TLS has the idea of built-in compression, in practice, that is never actually used.
This is determined mostly by the browser. Most browsers in TLS ClientHello send an empty compression algorithm list since they will use encoding headers (which let the servers cache the compressed data). A browser using Spdy could indicate it supports deflate to enable compression.
> Also, you claim that Google is basing this protocol on assumptions and you imply that they do not understand the value of metrics. I strongly disagree with this sentiment
Watch the tech talk video the other guy posted and drink when they say 'we assume' or to that effect. These guys do testing to confirm their assumptions. Take a look at when a questioner asks about high packet loss and how they hand-wave away Spdy being crippled by high packet loss.
> because SPDY headers are length-prefixed for ease of parsing. It compresses better when the prefix is included in the dictionary; such that {0x00,0x00,0x00,0x07,o,p,t,i,o,n,s,} would compress to one byte, not 5
No, wrong, that's not how compression works. Deflate uses lz to compress runs and repeats like \0\0\0 and it uses huffman to better encode it to bits.
Here's a clue for you, compressing "\0\0\0\7options" using deflate:
The first is the rfc draft dictionary, the second is that with only the first occurrence of each count, and the third with on \0\0\0 at the start and no other counts.
Not even to mention there is limited space in the prefix due to the window size and it sliding, so not only are the counts basically useless but they use space that could be used for other data.
I take it back... these people don't just lack rigor, they are clueless bordering on incompetent. As just an implementer I can accept that you don't completely understand the issues and are excited to work on the implementation, but as protocol designers from Google the work done with Spdy is just unacceptably bad.
> A browser using Spdy could indicate it supports deflate to enable compression.
This would cause everything on the connection to be compressed. Including things like images and videos, which are already compressed, and likely as not, will get larger when you recompress them.
> These guys do testing to confirm their assumptions.
This is how any science gets done... hypothesis, then experimentation
As to your comments on how compression works, I admit my lack of knowledge on how lz works. But I trust the results of the experiments done by the guys at the University of Delaware. If you have a better dictionary in mind, take their sample data, run the same experiment with your dictionary, and post your results on spdy-dev. That's how they got their change in the spec in the first place.
> ... but as protocol designers from Google the work done with Spdy is just unacceptably bad.
Any actual examples? If you had any real basis for your arguments, I'd be more than willing to back you up on spdy-dev.
> This is what boggles my mind about Spdy, the dissonance. On the one hand Spdy is great because it does a bunch of requests on the same TCP connection, but on the other hand Spdy is great because it saves 100 bytes per connection and that's a big deal because there are going to be so many connections made? It doesn't make sense.
Adaptability: SPDY works well for both cases, rather than only picking one case and optimizing for that case alone. I see quite a bit of value in optimizing SPDY for a pile of short single-request connections to sites, as well as optimizing for numerous requests to the same site. Google's own site will serve numerous examples of both; see below.
> On a first request only. You visit some site and only check if exactly one resource? Not likely. In any case, the cost to transfer 100 bytes once is irrelevant in any grand scheme of things.
It costs nothing to initialize the compressor state differently, and saves 100+ bytes per initial request/response.
A quick search suggests that Google services several billion searches per day. Assume for the moment that a substantial fraction of those searches come from user agents that don't already have an open connection to Google. Starting the compressor out with a specific state based on a prefix dictionary costs nothing (just changing the initial state of the compressor), but saves 100+ bytes per initial request/response. So, just for Google alone that change could save on the order of 100GB of traffic per day, for something that costs browsers and servers nothing to do. Now multiply that out for every other site on the Internet.
And for a different approach, consider the total number of initial connections that take place on GSM/3G networks every day.
More importantly than bandwidth, saving 100 bytes provides a potentially substantial latency benefit for the initial response, making it that much more likely to fit into a single frame rather than fragmenting.
If SPDY can save 100 bytes for free, why not do it?
That paper seems to compare their proposed dictionary to "SPDY’s current default initial dictionary", which as far as I can tell means the prefix dictionary from some iteration of SPDY, rather than zlib's default. I don't think the paper provides statistics on how much a prefix dictionary saves over not having one at all.
> The dictionary construction part is suspect though... take a look at how many times the same string length count (\0\0\0\4 for example) occurs in the prefix -- this can't be optimal.
I agree that the default dictionary could probably use work. That kind of work seems like the most likely reason for the several versions of prefix dictionaries that have appeared so far, which you complained about in a previous comment. :)
> So, just for Google alone that change could save on the order of 100GB of traffic per day
So say $150 dollars/mo? Or 0.00002% of their profit/year. Come on.
> I don't think the paper provides statistics on how much a prefix dictionary saves over not having one at all.
The paper compares plain, deflate, and deflate + prefix dictionary. Prefix is only a benefit on the first request and response, adding up to 121 on average in their test.
> The paper compares plain, deflate, and deflate + prefix dictionary. Prefix is only a benefit on the first request and response, adding up to 121 on average in their test.
As far as I can tell, it seems to compare plain, deflate with SPDY's current prefix dictionary, and deflate with the paper's proposed prefix dictionary.
You are correct, the paper does not compare to compression with a null prefix. In haste I read it wrong, since it was not too far off from calculations I had done previously in a reddit discussion where I found ~100 bytes saved using the prefix dictionary. Thanks for being persistent and I'll see if I can rerun their data using a null prefix before the next Spdy thread, but I doubt it will show more than 200 bytes total savings per connection, which doesn't change anything IMO.
My understanding is that HTTP/1.1 pipelining can break in a messy way where the client isn't sure whether some requests in flight will be serviced or not. Thus it tends to be disabled. In contrast, SPDY either works correctly or it falls back to regular HTTP.
There are some problems in HTTP pipelining. Nevertheless Firefox and Opera have pipelining implementations that work and are significantly faster than HTTP with keepalive. It's enabled by default in Opera.
The point being that they've designed this new protocol based on their assumptions and hunches. Same lack of rigor is present throughout the whole spec -- take a look at how much redundancy is in the prefix dictionary for instance.
Chromium and Chrome Dev Channel has (off by default) pipelining.
Pipelining can only be done for idempotent requests, (ie GET only), has head of line blocking problems, and can break proxies.
Also, its very difficult to handle errors in a pipelined situation. For example, if the 2nd request in a pipeline fails, but the server has been processing 3rd and 4th concurrently, what response does it give?
I think most engineers would agree that multiplexing over a single connection is better and less error-prone than pipelining.
Isn't security one of their major concerns? Before you encrypt something as compressible as headers, it's a good idea to compress it first. At the least, when brute forcing decryption keys, it makes it more complex to check the output.
Brute forcing a key shouldn't be a concern, nor should a known-plaintext attack be. If it is, your crypto is broken. That said, compression before encryption means there's less data to encrypt, so you win back some performance lost by the compression.
Nevertheless, I'm sure the considerations were something else entirely (such as compression seldom being done by TLS).
* various fields changed size
* compression dictionary [1] for headers block updated
* a few things clarified where spec was ambiguous
* CREDENTIAL frame, so multiple ssl certs can be used on one connection
* addition of per-stream flow control
The last two are probably the most work for implementers.
[1] Compression dictionary for header block: * Paper: http://www.eecis.udel.edu/~amer/PEL/poc/pdf/SPDY-Fan.pdf * The Dictionary: http://www.cis.udel.edu/~amer/PEL/SPDY/SPDY-proposed-initial...