Jbuilder is a DSL for compose JSON in Ruby. “It’s so cool”, that Rails give it us out of the box even in version 4.2. But, I think it’s not a perfect solution. Actually my first expression about Jbuilder was: “Hmmm.. What is this?! Looks like a template, but Ruby insets are everywhere!!” So I think Jbuilder is too complex and unhandy. It’s very difficult to use it from outside of controllers. For example if you Rails back-end provide pushes, it will be hard getting JSON from Jbuilder.

So we have a good alternative. It’s ActiveModel::Serializers: https://github.com/rails-api/active_model_serializers. It has very simple OO-DSL and you can use it anywhere like other Ruby classes. For example:

class MovieSerializer < ActiveModel::Serializer
  attributes :title, :year

  has_many :genres

# => {"movie" => {"title" => "Title", "year" => 2014, "genres" => […]}}

Very fun, isn’t? One my colleague someday said that AMS is much slower than Jbuilder. And here is little benchmarking about it.


I will use Rails 4.1.7 with Jbuilder 2.0 and ActiveModel::Serializers 0.9.0.

There are four different cases that I separated out:

  • Transforming single ActiveRecord object to JSON / array of AR objects

  • Transforming with render method of ActionController / without render method

Why I use render method? Because it’s the default way to deal with Jbuilder templates. You mostly store your Jbuilder as template in views directory, and much more less use it’s standalone through Jbuilder.new/encode. And the opposite ActiveModel::Serializers works pretty well with both variants of usage.

Sources of benchmarks are here: http://goo.gl/in1zbF

Single object with render

➜  ams_vs_jbuilder  rake benchmarks:single_object_with_render
Calculating -------------------------------------
            jbuilder        24 i/100ms
                           147 i/100ms
            jbuilder      229.5 (±13.5%) i/s -       1128 in   5.021995s
                         2743.3 (±16.0%) i/s -      13377 in   5.013579s

active_model_serializers:     2743.3 i/s
            jbuilder:      229.5 i/s - 11.95x slower

Single object without render

➜  ams_vs_jbuilder  rake benchmarks:single_object_without_render
Calculating -------------------------------------
            jbuilder       394 i/100ms
                           354 i/100ms
            jbuilder     5213.9 (±14.0%) i/s -      25610 in   5.003398s
                         4895.9 (±13.5%) i/s -      24072 in   5.010093s

            jbuilder:     5213.9 i/s
active_model_serializers:     4895.9 i/s - 1.06x slower

Array of objects with render

➜  ams_vs_jbuilder  rake benchmarks:array_of_objects_with_render
Calculating -------------------------------------
            jbuilder         4 i/100ms
                            42 i/100ms
            jbuilder       50.2 (±10.0%) i/s -        252 in   5.073880s
                          448.8 (±8.5%) i/s -       2226 in   4.995827s

active_model_serializers:      448.8 i/s
            jbuilder:       50.2 i/s - 8.94x slower

Array of objects without render

➜  ams_vs_jbuilder  rake benchmarks:array_of_objects_without_render
Calculating -------------------------------------
            jbuilder        36 i/100ms
                            45 i/100ms
            jbuilder      386.4 (±11.6%) i/s -       1908 in   5.002895s
                          488.1 (±9.8%) i/s -       2430 in   5.026865s

active_model_serializers:      488.1 i/s
            jbuilder:      386.4 i/s - 1.26x slower


You can see everything by yourself. Jbuilder wins ActiveModel::Serializers only in standalone variant of usage and only when use transform only single AR object, not an array. But the difference between Jbuilder and AMS in this case only 1.06x, it’s very close to calculating error.

And from opposite you can see, that in all another cases Jbuilder is much slower than ActiveModel::Serializers. And it’s the real world cases, because Jbuilder is mostly used with render method. And the results with render method are extremely bad for Jbuilder:

  • 11.95x slower than AMS with a single object

  • 8.94x slower than AMS with array of objects

I think for now there is really no reason to use Jbuilder. It’s very slow, too verbose and too complex for such simple task as transforming objects to JSON. You can use ActiveModel::Serializers and it will be handy and will cover all of your usage cases.

Happy programming with AMS!