Rabl In Production

nesquena edited this page Feb 15, 2013 · 7 revisions

When using RABL in production, you should definitely take a look at enabling certain 'production' configurations. Enabling these is the road to keeping RABL fast and scalable as the volume of traffic to your APIs grow. Be sure to follow the steps below.

JSON Engine

RABL supports lots of JSON engines. The engine you pick matters a great deal in terms of performance. In particular, be sure to check out yajl-ruby and oj. Using these with RABL is as simple as including them in your project:

# Gemfile
gem 'oj'

This can make a big performance improvement for serializing of large templates to JSON.

Configuration

When using in RABL in production, be sure to enable the following settings:

# config/initializers/rabl_init.rb
Rabl.configure do |config|
  config.cache_all_output = true
  config.cache_sources = Padrino.env.to_s != 'development' # Defaults to false
  config.view_paths = [Padrino.root.join("app/views")]
end

If cache_sources is set to true, template lookups will be cached for improved performance. The cache can be reset manually by running Rabl.reset_source_cache! within your application.

If cache_all_output is set to true, every template including each individual template used as part of a collection will be cached separately. Additionally, anything within child, glue and partial will also be cached separately. To cache just a single template, see the section titled 'Caching' below.

Setting the view_paths at this level make the view lookups faster then forcing RABL to be 'smart' with your view paths. Set this explicitly if you can.

Caching

You should also setup proper cache keys on all your templates. Read the Caching Guide for more details.

Performance Issues

If you experience performance issues with RABL, please be careful to isolate unrelated issues. For instance, often the slowness lies in an N+1 query with your data. This can be very common and there's nothing RABL can do to protect you. Be sure to use a plugin like Bullet to identify and resolve N+1 issues.

In addition, slowness can occur due to overly complex templates or excessive use of extends or partial so try to be judicious with this. Another common culprit is excessive helper invocations calling helpers for a large number of records. More generally, if you are rendering > 100 records (or worse > 1000) in a single RABL template, you can start to see significant slowdowns. Consider using pagination and/or other strategies to avoid rendering huge sets of items into JSON within your API. This is beneficial even from a design perspective and not just for performance.

If none of this helps and the slowness is becoming a major problem, please raise an issue, we can help!

NewRelic

If you use NewRelic to monitor the performance of your application (and you probably should!), then you are granted a great visibility into the slow parts of your controller actions. Sometimes though, the information presented can be a bit confusing. In particular, when templates are slow, often NewRelic simply doesn't explain why.

First, if RABL (or any templates) are slow only in arbitrary cases, be sure to be on the lookout for GC sweeping. Make sure to enable GC monitoring on your ruby applications. Also, be sure to tweak your GC settings to have the ruby processes startup with more allocated memory. Often the slowness is simply because by default the GC is very aggressive and yet far too conservative with initial GC allocation.

If none of this helps and the slowness is becoming a major problem, as mentioned above please raise an issue, we can help!

RABL Performance Resources