Skip to content

2010

The Long Tail

One of the questions in a technical interview I sat today was "Write 'tail' in Ruby". I had a pen and paper and no access to Google. I think I came up with a reasonable solution but I realised how dependent I am on docs! It took me a long time to arrive at a solution when I couldn't refer to Ruby API docs.

#!/usr/bin/env ruby

filename = ARGV[0]

end_marker = 0
offset_increment = 1000

lines = []
fh = File.open filename
while lines.size < 10
  current_offset = end_marker + offset_increment
  fh.seek(-current_offset, IO::SEEK_END) || fh.rewind
  buf = fh.read(current_offset - end_marker).split("\n")
  lines.insert(0, *buf)
  end_marker += current_offset
end
puts lines.last 10

Hmm, it's still kinda broken.

Strange HTTP Performance Variations Between OS’s

[2013-12-19 I let latentsee.com lapse but you can still install latentsee on your own webserver]

In a recent talk at VelocityConf, John Rauser explained the effect of TCP Slow Start and Congestion Control on web performance. He pointed out that RFC 1122 states:

Recent work by Jacobson on Internet congestion and TCP retransmission stability has produced a transmission algorithm combining "slow start" with "congestion avoidance". A TCP MUST implement this algorithm.

While examining the impact of these with my new HTTP performance testing tool (LatentSee) I noticed that the charts generated on my Mac & Windows machines didn't seem to match the theory. Usually we would expect to receive 3 packets (< 4500 bytes) in the first segment. Instead I am seeing up to 67KB on the Mac and around 35KB on Windows 7.

Effect of file size on retrieval time from slicehost.latentsee.com

Original images: | Theory | Ubuntu | Windows 7 | Mac OS X

When I ran the same tests against a different hosting provider (Brightbox), Windows and Mac OSX behaved more like my Ubuntu box.

Effect of file size on retrieval time from brightbox.latentsee.com

Original images | Theory | Ubuntu | Windows 7 | Mac OS X

I'm very curious about these differences. It takes the same time for my Mac to retrieve any file up to 67KB in size from Slicehost. Have they tuned their TCP stack differently? Why then does Ubuntu behave similarly against both Slicehost and Brightbox? Is everyone conforming to the RFCs?

I'd love to hear if people can reproduce these results.

You can experiment with LatentSee using your web browser. - USA: slicehost.latentsee.com - UK: brightbox.latentsee.com - AUS: ultraserve.latentsee.com

You can also put latentsee.php on your Apache webserver to test your own servers (be sure to disable compression on the vhost).

TCP and the Lower Bound of Web Performance - John Rauser

I was fortunate enough to be in the room for this talk by John Rauser at Velocity 2010. I realized a few minutes in that this talk was (a) super interesting and (b) not being filmed. So I pulled out my Flip and caught most of it.

This talk inspired me to plot some real world data to test the theory.

The slides from the talk are here.

See Also: John Rauser's "Look At Your Data" from Velocity 2011

Latency is a Killer

If you're hosting your website overseas you might want to rethink. I've been doing some research on the true impact of hosting Australian websites in the U.S. and it's worse than you might think.

I plotted the time it took to retrieve 200 files from 1-200KB from two locations. The first was a server in the same city as me (kindly provided by SCT.com.au) and the second is with Slicehost in the US. We're comparing the effects of 15ms RTT vs. 250ms RTT on performance.

You might imagine the US server would simply add 250ms to the total download time. The reality is that it can take ten times longer to get files from the U.S. The TCP protocol includes provisions to avoid network congestion that were designed before we had broadband. I discussed these in my presentation 'Speed Matters' (slides here).

The Effects of Latency on Load Time The Effects of Latency on Load Time

source data

The stepping you see is due to TCP Congestion Control (RFC 2581) and Delayed ACK (RFC 813).

My investigation was inspired by a talk by John Rauser at VelocityConf last month.

Speed Matters

Velocity 2010

Last week I lucky enough to attend O'Reilly Velocity 2010. In the heart of Silicon Valley, 1200 geeks assembled to discuss how we can make the web faster. We listened to techies from Amazon, Google, Yahoo, Facebook, Twitter, Microsoft, Firefox, Firebug, Chrome, and more talking about web performance and operations. The trip was worth it. Check out the videos.

Last night I had the opportunity to present a little of what I've learned about Web Performance to the Melbourne Ruby User Group. It's clear from feedback that we care about reducing page load times and most of us have used performance analysers like YSlow. Folks appreciated metrics from Google, Amazon and Wikia that show a small difference in page load time (100ms) affects sales, abandonment and conversions. This kind of thing helps us make a business case to employers and clients for speeding up the web.

Australia is a "special place" network wise. The insane cost of bandwidth and services means many of us choose cheap hosting in the U.S. even when the majority of our users are in Australia. This means choosing increasing latency from ~20ms to >200ms. Latency affects TCP performance even more than most of us would guess. I'm currently looking into just how big a difference this makes.

Which leads to the next question, where are the great VPS and DNS services in Aus? Suggestions appreciated!

View more presentations from mbailey.

At least amongst visitors to my blog yesterday.

Browser usage

And no, I don't normally get 240 visitors to this blog but I'd just made an announcement that obviously appealed to people with good taste in browsers!

Asset Fingerprinting with Paperclip

Update: My Asset Fingerprinting patch was included in paperclip-2.3.4 in Oct 2010. Thanks jyurek!

One of the tricks to improving the performance of your website is to optimize caching. By instructing browsers and proxies to cache assets that don't change very often (css, images, javascript), we can reduce page load time as well as bandwidth costs.

By instructing browsers and proxies to never check for updated versions of cached assets we can further speed things up. Google recommend the use of fingerprinting to enable dynamic updating of cached content. This simply means including a fingerprint of the resource in it's URL so the URL gets updated when the resource changes.

paperclip

Paperclip is a popular file attachment plugin for Ruby on Rails. It was a perfect candidate for fingerprinting support as it generates resource URLs from stored data.

Enabling it is as simple as:

  1. Install paperclip-2.3.4
  2. Add an :attachment_fingerprint column to your database
  3. Include :fingerprint in the path for your attachment (see below)
has_attached_file :avatar,
  :styles => { :medium => "300x300>", :thumb => "100x100>" },
  :path => "users/:id/:attachment/:fingerprint-:style.:extension",
  :storage => :s3,
  :s3_headers => {'Expires' => 1.year.from_now.httpdate},
  :s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
  :use_timestamp => false</code>

This enables us to set far future expire headers so that browsers don't need to check for a newer version. If a change does occur, say because a user uploads a new avatar, the new filename will be rendered in your html and the cached version will be ignored.

The example above will set Expires headers in S3. If you're using local storage you can configure your webserver to do something similar.

We disable the timestamped query string because some proxies refuse to cache items with query strings.

Fingerprinting support was added to paperclip-2.3.4 on 6 Oct 2010.

For more info on optimizing for caching:

http://code.google.com/speed/page-speed/docs/caching.html