"Transaction counts on the other nodes are pretty similar (within about 2%), and all those nodes are also exchanging transactions. Yet I am qualitatively seeing very different compression ratios on the same blocks going to different nodes some of the time."
I haven't seen the same thing....however, sometimes, when you're starting up a node it takes a while for the mempools to catch up and sync and in our case the last few days with all the spam going on it can take 12, 24 hours or more with a lot of very big spam transactions out there. Consider that if you are missing just 4 spam transactions of 15KB each that makes a big difference for the thinblock. I think you will see very different and more consistent results, as I have, when traffic is more normalized or you have been running your node for several days.
"This could be because the bloom filter is lost in transit, arrives slower (I forget is this TCP?), is somehow reordered by the send logic, or is not processed fast enough or out of order in the receive."
I don't see how any of those events above could either happen or have an impact on thinblock size.
One thing that you are touching on though is that, if we could have mempools in perfect sync then yes we can drop the bloom filter without incurring a re-request. I was thinking about this as an approach to a fast block relay or "Lightning block relay for miners" where we could have an advanced mempool sync, drop the bloom filter and just send a headers first (no inv) with the coinbase transaction and with the tx hashes, basically a thinblock without transactions, the only requirement is that the receiving node would have to run a very large mempool.
But back to your question, yes we could drop the bloom filter now also, but then you will have to do a re-request every time which depending on network activity can be quick or take a while. With our single threaded network layer it's hard to predict how fast those re-requests take...i've seen them vary quite widely at times when the network gets busy. That's really in the end the value of using the bloom filter, which is to prevent re-requests and keep block propagation moving forward as quickly as possible.
[doublepost=1455771561,1455770561][/doublepost]
@theZerg That is food for thought though, maybe in the next iteration we could make use of the headers first functionality in v12 and make it Thinblocks first (when we announce the block) but without the transactions, just the hashes and the coinbase and then do whatever re-request is needed, then we could drop the inv/getdata with bloom filter and be at least as fast and sometimes faster if all the tx's are in the mempool.