
Rails 3.2 Performance: Another Step Slower - wbharding
http://www.williambharding.com/blog/rails/rails-3-2-performance-another-step-slower/
======
tenderlove
We take performance very seriously, but we can't locate and fix every perf
regression on our own. If you can give us metrics and repro code, we can work
to fix the issues.

~~~
wbharding
Thanks Aaron. I imagine I'll probably spend Thanksgiving weekend trying to dig
further into what is newly slow on our 3.2.15.

The trick with pinpointing a cause is that when I look at the data NR
provides, every partial rendered and every action called is slower than it had
been previously. Combined with the immensity of our codebase, it's going to be
time-consuming to put a finger on a single repro-able cause. But we'll do our
best to isolate and report back.

FWIW, have you guys ever considered creating a performance suite test app?
With such sparse Google results around Rails performance changes over time, it
could be useful to compare the performance of Rails versions on an apples-to-
apples basis if we could see how the performance of the test app changed over
Rails versions. If we're lucky, it might even catch some of the performance
regressions that have happened in the dot releases previously. Even if not, it
would at least demonstrate that performance is an important consideration in
Rails' evolution. I'd sleep better knowing that.

Maybe take a popular mid-sized framework like Spree and see how it performs on
3.0, 3.1, 3.2, etc.?

~~~
sams99
If you send me a flamegraph using ?pp=flamegraph_embed I can help you figure
out why it got slow.

I am actively working on getting a long term perf benchmark using the
Discourse bench. Server is already provisioned by ninefold. see my talk
(towards the end) [http://www.youtube.com/watch?v=LWyEWUD-
ztQ](http://www.youtube.com/watch?v=LWyEWUD-ztQ)

~~~
gary4gar
You are doing god's work with Discourse & improving rails/ruby to support
50/ms response/per request.

Thank you!

------
cheald
Ruby has some great tools to isolate and fix performance issues. In
particular, ruby-prof and kcachegrind (or qcachegrind) are tremendously
valuable resources for tracking down and eliminating performance bottlenecks.

I did a writeup on it a bit ago here:
[https://www.coffeepowered.net/2013/08/02/ruby-prof-for-
rails...](https://www.coffeepowered.net/2013/08/02/ruby-prof-for-rails/)

~~~
wbharding
Thanks cheald. Will take a look at those. My problem with using the
performance tracking tools in the past has always been that I get output like
"100k string allocations," "3500 ActiveRecord objects instantiated," "6000
ActiveSupport methods executed," etc. With so much complexity in Rails, it can
be maddeningly difficult to pick a culprit from amongst the 1000 papercuts
that tend to slow an app down.

Even if we just arbitrarily said "let's focus on whichever method is
cumulatively taking most time," we have no reference point for whether Rails
could make that method faster or not. The time taken by a method or
instantiation is just some number, and whether that number is "good enough" is
ultimately a judgement call in which I have little basis for comparison.

I hope I'm wrong and that there are some big obvious things to optimize, but
when I've gone down these rabbit holes in the past, my experience has been
that there's usually so much data and so many pieces things contributing to
slowdown that it's hard to find high-impact things to fix. Especially when it
comes to a framework as multilayered & complex as Rails.

~~~
cheald
If you want to email me a gzipped callgrind or two, I'd be happy to take a
look and see if I can make any suggestions. You can reach me at cheald @
gmail.

------
matthewmacleod
I've upgraded several Rails apps from ~>2.3.0 through to 4.0. I saw
performance regressions around Rails 3, and they've subsequently disappeared
when upgrading to 3.2 and 4.0 - the latter in general being much faster.

I have to wonder what you're doing that's giving you an average of 480ms? Have
you stripped out middleware you're not using? Have you looked into exactly
where the time is going? There are so many places to start, it's hard to offer
much concrete advice.

------
jordanthoms
I just wish someone would find it in their economic interest to do for Ruby
what V8 did for Javascript. Doesn't seem like there is any fundamental reason
for Ruby to run slower - it's just a matter of putting the (substantial)
resources in to make it happen. JRuby might be the solution to this though, if
they can catch up with MRI's functionality and stay on par.

~~~
cygwin98
Twitter was in a nice position to better Ruby in terms of performance, though
they chickened out and escaped to Scala.

Even Twitter went public recently and posed to challenge big guys such as
Google, Facebook, they've lost my respect as a technology company.

~~~
laureny
> Twitter was in a nice position to better Ruby in terms of performance,
> though they chickened out and escaped to Scala.

Actually, they escaped to the JVM, and if their job reqs are any indication,
they hire massively for Java engineer positions and hardly at all for Scala
ones.

I wouldn't call that chickening out, more common sense.

Rails is great for prototypes and toy apps, but once you start needing scale,
it's simply not up to the task.

~~~
why-el
> Rails is great for toy apps

This gets said here a lot. What about GitHub and Shopify, and ...? Are those
toy apps?

~~~
porker
I'm curious too how much of each of these is still built on Rails, and how
much has been tweaked, tuned and rewritten to be 'inspired' by Rails, but no
longer Rails.

~~~
why-el
Good question. I would say it varies, but after all they are mostly likely not
changing things dramatically, at least thats what you get from watching talks
from both companies[1].

[1] [http://www.slideshare.net/jduff/how-shopify-scales-
rails-204...](http://www.slideshare.net/jduff/how-shopify-scales-
rails-20443485)

------
darkbot
I've upgraded several apps, I've been on the Rails train since 1.2, and each
time there's been slight, and more often major, performance gains. Yes, some
of these apps where big (Not Twitter big, but big enough. And no, they didn't
need to do anything too crazy hardware wise.)

Almost all Rails apps that are slow on performance suffer from architectural
flaws or oddities in the code. A lot of time Rails get a beating when it boils
down to slow, illformed SQL queries. One time I had a customer who wanted me
to rewrite their platform because "Rails was so slow", when in fact they did
some heavy image processing and uploading to a cloud storage within the
browser request. I'm not saying OP does any of this, but since I don't know
any details about their codebase or infrastructure I'm making some general
remarks that may or may not apply.

Ruby code can be written in so many ways, I guess that is its blessing and its
curse. There are bad ways to do things, and there are good ways. With great
freedom comes great responsibility.

I would encourage OP to push on and upgrade to Rails 4.0.1. The gap between
Rails 3 and Rails 4 isn't that huge at all. I'm sure you'll be pleased.

------
memracom
Rails is not for building big apps. It works better for small, even quick and
dirty apps. When you want to build something that is big or that will evolve
into big, choose a better language and don't rely on a framework to save you.
In fact even big apps are better broken up into many separate functional apps
integrated by things like an RDBMS or a message queue broker or a NoSQL
cluster.

And you really need to think hard about caching. There are many layers at
which you can cache stuff and when you get into caching parts of pages, there
is a whole architectural design issue around how to divide things up.

In solving these kinds of problems Rails and its overly simplified
ActiveRecord pattern, just don`t give you much wiggle room.

~~~
mattdeboard
I've been thinking a lot of the same thoughts about Django. I'm tempted -- but
far too lazy -- to write a decision tree about using Django (which would
probably also apply for rails). I really love your comment, _Don 't rely on a
framework to save you._

Django is great for consultants/contractors who need to crank out work fairly
quickly that may be quite similar to other jobs they've got on the docket.
It's great for new programmers or programmers who aren't familiar with the OS-
level interactions between a web server and a programming language. It's great
for apps with very low complexity (current and projected).

Once you start getting out of these use cases though, IMO, you are asking for
trouble getting too invested in the Django (or Rails) ecosystem. It's worth it
to learn about how the web server interfaces with the language runtime, so
that you can capitalize on microframeworks. When you buy into a framework,
you're buying into a huge set of opinions about really important things that
have been made based on being flexible enough for about anyone.

I love Django for what it has enabled me to do in my life, and have learned
so, so much from getting into its guts to solve problems. That said it would
take a lot for me as a salaried, in-house software developer to start a new
project using (Django | Rails).

------
5vforest
For what it's worth, apparently the Basecamp team was hitting ~50ms request
times with their new (well, now it's not that new) design:
[http://37signals.com/svn/posts/3112-how-basecamp-next-got-
to...](http://37signals.com/svn/posts/3112-how-basecamp-next-got-to-be-so-
damn-fast-without-using-much-client-side-ui)

All technology has its trade-offs. Rails can be plenty fast, it just all
depends on how you're using it.

~~~
anonyfox
It'ns not that Rails is that fast (it isn't), they simply cache every damned
piece upfront. When your requests barely ever touch the rails but are satified
from the cache, you can use nearly everything as your backend stack.

~~~
rartichoke
This is exactly why I started to use rails recently. If it becomes pretty easy
to cache everything and you get the amazing productivity boosts that rails
provides you then there's really no down side.

My first rails app is approaching 4k lines of code and responses that are
cached using fragment caching are rendered in 5-8ms usually on a micro EC2
instance (aka. really bad hardware). I'm using MRI with rails 4.0.1 and I have
not done any tweaking. Just basic caching that was trivial to implement and
running rails in production mode which is just setting an ENV variable.

~~~
anonyfox
You'll encounter the downsides when you have to do some serious number-
crunching or analytical queries. Or just highly dynamic views that aren't
cache-able.

But that's not rails' fault, we all know that ruby itself isn't the fastest
language to develop in, the "bloat" of rails just increases this a little.

As long as you have enough cheap hardware to throw at all these problems,
everything should be fine, though.

~~~
rartichoke
I'm not too afraid of number crunching because if I do need some type of
analytical report crunching done I'll just chuck them in a sidekiq worker and
use the whenever gem to setup a cron job.

I already setup sidekiq to work with e-mails and have whenever being used to
generate a new sitemap once a day.

And tbh I don't think I'll ever go too crazy with highly custom analytical
queries either because google analytics is quite strong with custom event
trackers and tools like new relic are excellent for system health and
performance metrics.

As for highly dynamic views that can't be cached then I would worry about them
when the time comes. Maybe there's a way to setup varnish or nginx with SSIs
to deal with that, it's something I never researched in depth but have to
assume is a solved problem at this point with a little elbow grease and
technical knowledge.

------
Ensorceled
The original article seemed to be saying "Rails shouldn't get slower with
every release" but almost everybody seems to be replying as if it said "Please
help me make my Rails application go faster because I'm an idiot" ... did I
just misread?

~~~
mikkelewis
Debugging a large application on Rails for performance issues is a non-trivial
task. I wouldn't be so quick to assume.

~~~
Ensorceled
I didn't assume the author was right. I was pointing out the disparity between
the point of the original article and the comments.

------
sams99
Yes, would very much appreciate some flamegraphs
[http://samsaffron.com/archive/2013/03/19/flame-graphs-in-
rub...](http://samsaffron.com/archive/2013/03/19/flame-graphs-in-ruby-
miniprofiler) comparing the apps behavior on 2.3 and your latest (and 4.0)

Without exact profiling information its very hard to fix these issues.

------
gesman
It takes quite a bit of scrolling down to find Rails performance on this page:

[http://www.techempower.com/benchmarks/#section=data-r7&hw=i7...](http://www.techempower.com/benchmarks/#section=data-r7&hw=i7&test=query)

No surprises here.

~~~
VexXtreme
Thanks for this, it's a pretty useful comparison chart.

I don't know why the Rails community gets their panties in a bunch every time
someone brings up the poor performance of rails. It is a a slow bloated
framework that requires you throw hardware at your scaling problem instead of
writing decent code. In the end, there is only so much hardware you can buy
before your app stops scaling and you need a complete rewrite, the way Twitter
did.

~~~
matthewmacleod
Let's shut that trope down right now.

Ruby is slow, and Rails is slow, although they are both much better than it
used to be.

But this isn't bloat. Rails is a large framework that provides moderately
sensible defaults. The tradeoff of that is there's a lot of stuff in there
which might not be used by every app. This, and the overall flexibility of the
framework, can cause performance to suffer, and combined with Ruby's
relatively lacklustre performance, that can cause big scaling problems.

Twitter is a poor example though, given the somewhat unique problem space it's
tackling. But - building a standard e-commerce or service site? No problem.
Getting bigger? Add some hardware. Still not enough? Start customising the
framework. Because it's a toolset, not a one-size-fits-all solution. And if
you've got outsize scaling requirements, you are going to have to get your
hands dirty.

~~~
steveklabnik
The difference between 3.2-stable and master is +14k/-19k:
[https://github.com/rails/rails/compare/master...3-2-stable](https://github.com/rails/rails/compare/master...3-2-stable)

The difference between 3.2.13 and 4.0.0 was +121k/-103k
[https://github.com/rails/rails/compare/v3.2.12...v4.0.0](https://github.com/rails/rails/compare/v3.2.12...v4.0.0)

So yes, it has grown, but only a little, and may even be a bit smaller,
depending on how you compare.

------
charlesju
You can easily get your APEX back up without blaming Ruby. There is nothing
inherent to Ruby that should stop you from doing that.

More likely than not you probably have a couple nasty requests that should be
handled by a background task and a few more or less caching calls.

Additionally, from your user's perspective, 300~ish ms is already pretty good,
I wouldn't worry about that too much. You use Ruby on Rails because it is
speed on speed for rolling out features. Focus on a better user experience
with pretty good performance and you guys will be alright.

------
xs_kid
OH: "Stupid Rails team. Why can't you fix performance issues based on
anonymous New Relic stats alone?"

~~~
kibibu
Doesn't "OH:" mean "Overheard:"?

------
rurounijones
> Maybe a partnership with New Relic could help the Rails team to see the real
> world impact of their decisions on the actual apps

Last time I used NewRelic they gave you an option of sending anonymised
statistics to the rails core team.

The stats given in support of this claim are very weak as well. An over-all
average is pretty useless for determining the cause. It could be over-all
faster with more high outliers skewing the average for some reason. Need more
detailed information.

On a side-note, it took me 3 tries before I got the site and not an HTTP 503
error which is rather ironic given the situation.

------
dynjo
My car won't go fast, can someone tell me why?

------
toobulkeh
While I'm new to the rails scene, and can't speak for the 2.x -> 3.0
performance change, what surprises me is that this post is upgrading because
of newer gem support.

It this purely a rails upgrade? Or is the OP upgrading other gems at the same
time?

You're using newrelic. Use it, and figure out exactly where it's getting
slower. Do an entire stack trace. You can figure out exactly where those pages
have gotten longer responses. Then you can suggest to the rails community
what's slow for your application.

The platform is only as good as the community makes it to be. Maybe it's
missing your case's optimizations because you haven't given specific feedback?

~~~
joevandyk
newrelic isn't going to tell you that route url generation has gotten 2x
slower, or that calling pluralize 100 times is causing the slowness. all
you'll see is that a template takes a while to render.

------
mickeyben
Did you try to remove the parts of Rails you don't need? (ex: middlewares).

Also in New Relic you can look what's slower (ruby, db, rendering, request
queuing, ...). Could you give us more details.

Also your average is 423ms, but what's fastest pages like?

------
joeblau
I'm inheriting a Rails app and I'm thinking of switching it over to Node.js
for performance reasons. Most of the code currently implemented is pretty
basic and it's all Rails but we're already having performance problems are
we're still in beta. I've used Rails before, but I'm not guru and I wanted to
know if someone could point me to some resources for tweaking Rails
performance?

~~~
darkbot
Definitely stick with Rails, the framework will give you the training wheels
you probably need. Switch to Node.js and you'll probably end up with bowl of
noodle code soup.

Railscasts has a bunch of episodes covering performance related topics
[http://railscasts.com/?tag_id=1](http://railscasts.com/?tag_id=1)

~~~
joeblau
Yeah, I've really been liking what I've seen from Rails so far. It seems like
there is a lot of support for a lot of functions/features that you just
generally need which is awesome.

------
AwesomeTogether
Rails performance tip: [https://engineering.groupon.com/2013/misc/i-tier-
dismantling...](https://engineering.groupon.com/2013/misc/i-tier-dismantling-
the-monoliths/)

~~~
roin
I realize your comment is snark, but the lesson I take is to build your app in
Rails, then if you become multi-billion dollar IPO-level success, rewrite...

~~~
apkdn
The lesson you've learned is to pile on technical debt?

The real lesson is: if you can write your app in a much faster framework with
equivalent development speed, why even waste time to write it in Rails.

------
laureny
> The server is temporarily unable to service your request

Performance is apparently not Rails' only problem.

~~~
straws
That's wordpress. . .

------
andyl
So - just now you're upgrading to Rails 3.2 - nearly two years after it was
released?

In 2016 you're gonna love Rails4 - its got some nice support for caching and
client side rendering.

~~~
regularfry
This is not an uncommon thing. Not everyone can immediately jump on the latest
and greatest.

