At FiveRuns, we have a set of installed clients which upload data to our service periodically. Because of the way it is implemented, Rails is quite slow in handling file uploads. Merb is an alternative, albeit much simpler, stack to Rails which handles file uploads in a much saner manner. The performance difference is quite large.

Optimizations

Merb -- turned off ActiveRecord, environment to production, log level to warn, disabled sessions globally.

Rails -- environment to production, log level to warn, disabled sessions for the controller.

The Merb controller code:

  def put
    FileUtils.mv params[:file][:tempfile].path, MERB_ROOT+"/uploads/#{params[:file][:filename]}.#{next_count}"
    render :action => 'index'
  end

The Rails controller code:

  def put
    File.open(RAILS_ROOT+"/uploads/#{params[:file].original_filename}.#{next_count}", "w") { |f| f.write(params[:file].read) }
    render :action => 'index'
  end

I used Apache JMeter to create a group of 25 users trying to upload a 250k image as fast as possible. On a side note, I can't recommend JMeter highly enough. I downloaded it and was generating this load within 10 minutes. The user manual walked me through the basics and the UI had exactly the controls I need to create the FORM POST.

Without further ado, here's the results.

merb resultsrails results

I'm not sure how to read these results. Merb's average response time is 16 ms while Rails's average is 205 ms (over 10x faster), yet the throughput is 3000 vs 2000 req/min (only 50% greater). Note that Merb seems to be much more deterministic in the response times. Rails response handling times appear to fluctuate wildly while the Merb results have a much tighter standard deviation. These results remind me of the old proverb: "Data is not information and information is not knowledge". While the specifics are still a little unclear, it is clear to me that Merb is several times faster than Rails at just handling file uploads.

comments powered by Disqus