Ruby on Rails Scalability – Is it a Problem?
Nick Wilson caught my eye on his new podcasting blog communicontent.com when he stated/asked “Ruby on Rails doesn’t scale?”. Its no secret that we’ve been shifting the NotSleepy shop from a PHP on the front, Java on the back setup to Ruby on Rails for the past few months. In fact we started a new RoR training side business with David Black, and have been building a new suite of tools from scratch in Rails. The experience has been nothing short of revolutionary for me and has been more liberating than switching from briefs to boxers in my teens. So when someone claims I’m not going to be able to scale this thing I felt my heart sink.
Unfortunately Nick doesn’t go into detail as to what the specific bottleneck was for CrazyEgg but after speaking with a few friends and reading DHH’s entry on scaling Rails, I’m thinking its an issue of an architect that doesn’t know how to scale his app or has coded the system poorly. David Hansson’s point is that if you design your system to not maintain state at the app level and keep in line with shared nothing at the app level, then you can easily scale infinitely by adding more app nodes much like LiveJournal, eBay and even Google do. David concedes that Rails can only handle half as many requests per second as PHP and therefore you are roughly going to have to spend $500 a month for 2.6 million requests/day on Rails versus $250 on PHP. If you’ve built a Rails app you know this is absolutely an inconsequential cost compared to the additional cost of man hours to build, maintain, and enhance a PHP app.
There aren’t a lot of mega traffic sites running on Rails yet but CrazyEgg certainly isn’t touching the traffic 43things brings in daily. Also, a friend of mine runs SoulCast and while I don’t know his daily stats I imagine he does as many pages views a day as CrazyEgg and I’ve never seen the site lag.
Update
Holy crap what a small internet world it is! Ok, after blogging this I was just sending a few emails reaching out to some folks I hung out with at Pubcon Vegas last week and I didn’t get a card from Neil Patel so in the process of hunting down his email I discovered that he is CTO for the company that built CrazyEgg and now I feel like an ass. Sorry Neil. I’m absolutely sure you are a skillfull architect and look forward to hearing more details.
Update 01/26/2007
I didn’t want to create a new post so I decided to append to the bottom of this post. David on scalability in the middle of a very long thread I just discovered. Great synopis and worth your time if you are still on the fence:
I've said it before, but it bears repeating: There's nothing interesting about how Ruby on Rails scales. We've gone the easy route and merely followed what makes Yahoo!, LiveJournal, and other high-profile LAMP stacks scale high and mighty. Take state out of the application servers and push it to database/memcached/shared network drive (that's the whole Shared Nothing thang). Use load balancers between your tiers, so you have load balancers -> web servers -> load balancers -> app servers -> load balancers -> database/memcached/shared network drive servers. (Past the entry point, load balancers can just be software, like haproxy). In a setup like that, you can add almost any number of web and app servers without changing a thing. Scaling the database is the "hard part", but still a solved problem. Once you get beyond what can be easily managed by a descent master-slave setup (and that'll probably take millions and millions of pageviews per day), you start doing partitioning. Users 1-100K on cluster A, 100K-200K on cluster B, and so on. But again, this is nothing new. LiveJournal scales like that. I hear eBay too. And probably everyone else that has to deal with huge numbers. So the scaling part is solved. What's left is judging whether the economics of it are sensible to you. And that's really a performance issue, not a scalability one. If your app server costs $500 per month (like our dual xeons does) and can drive 30 requests/second on Rails and 60 requests/second on Java/PHP/.NET/whatever (these are totally arbitrary numbers pulled out of my...), then you're faced with the cost of $500 for 2.6 million requests/day on the Rails setup and $250 for the same on the other one. Now. How much is productivity worth to you? Let's just take a $60K/year programmer. That's $5K/month. If you need to handle 5 million requests/day, your programmer needs to be 10% more productive on Rails to make it even. If he's 15% more productive, you're up $250. And this is not even considering the joy and happiness programmers derive from working with more productive tools (nor that people have claimed to be many times more productive). Of course, the silly math above hinges on the assumption that the whatever stack is twice as fast as Rails. That's a very big if. And totally dependent on the application, the people, and so on. Some have found Rails to be as fast or faster than comparable "best-of-breed J2EE stacks" -- see http://weblog.rubyonrails.com/archives/2005/04/04/justingehtland-is-back-with-numbers-to-back-it-up/ The point is that the cost per request is plummeting, but the cost of programming is not. Thus, we have to find ways to trade efficiency in the runtime for efficiency in the "thought time" in order to make the development of applications cheaper. I believed we've long since entered an age where simplicity of development and maintenance is where the real value lies. David Heinemeier Hansson Tuesday, July 12, 2005
Tony,
The issue we have experienced Crazy Egg are not based on the fact that we serve a lot of pageviews per day, but instead are related to what our service is doing. The websites that you mentioned above have significant amount of pageviews and there is a lot of documentation available as to how to scale those types of websites. Crazy Egg is essentially an analytics product where people put a javascript code on their website, so we can track the clicks on their webpages. These are the same types of issues that MeasureMap has in relation to Rubyonrails and scaling an analytics application using Rubyonrails. We have actually made significant progress since we launched about 3 months ago and are scaling Crazy Egg successfully as we speak
Oh cool and thanks for giving more information Hiten! I’m curious if the issue is with the reporting side of the app or with persisting the clicks in a DB?
Can you go into detail as to how Ruby on Rails is specifically causing scalability issues?
Hiten and I chatted on the phone this week and I must say that even though he prefaced the conversation by stating that he wasn’t a techie, he spoke more like a system architect than any other CEO I’ve met! Dude knows his shit.
So in a nutshell Hiten tells me :
Rails scales fine. Great. Fantastic even.
To speed up click tracking they’ve moved that to native C.
Rails can easily handle 10’s of millions of pageviews a day.
Sweet.
As far as I see RoR is more then twice slower then php – If you add unstability it’s obvious : it’s too early for RoR to become a solution for big apps. I’m dealing with two product in my company – one is RoR/Mongrel based and second PHP/Java/Apache/Tomcat based : we were many times in trouble because of RoR. You can optimize PHP much better even with some own c++ php modules it’s possible to get rid of Java/Tomcat part and that will make it double fast – I have to say – RoR it’s getting better and better – but as I mentioned before – it’s too early for ROR
Ofcourse RoR is slower than PHP. But the amount of work you need to spend on developing it in PHP/JAVA (unless you are using any MVC framework) will be very different.
If your Java app scales like 60requests/second, for RoR it can be 40r/sec. You setup more machines to scale it to reach 80r/sec. You spend less on development and spend more on hardware. At the end of the day you will find out why ‘Build first, scale later’ will happen to be economical. Simple funda.
See wonderful casestudies on Rails scaling
http://www.webforth.com/2007/04/scaling-twitter-to-the-maximum
When scaling up a Rails app, remember to use caching wherever possible. There are a few caching modules available in Rails (actions, fragments, pages) that are simple to plug in, though I’ve found fragment caching to be the most useful.
Just as an example, this entire blog post with comments only needs to be regenerated when a new comment is submitted. There’s your fragment.
The further you shift to static content, the further the Rails vs. PHP vs. … argument shifts to Apache vs. Lighttpd vs. …