I don't think anyone seriously argues that it's impossible to scale Ruby websites, and make them run quickly with caching and various optimizations.
Rather, the trouble with Ruby (and Rails) is that you end up having to implement these optimizations much faster than with a lighter-weight setup (like PHP on top of a vanilla database, with no ORM).
Hence all the discussion about your "stack", middleware, load-balancing, front-end servers, merbs, mongrels, passengers, and all the bewildering variety of gems required for the care and feeding of a production app. Rails developers write about armoring their app with all this extra stuff in a way reminiscent of MMORPG players equipping a character for battle.
It's a legitimate trade-off, and many people seem comfortable making it. But posts like this sidestep the issue. It's not that Ruby can't scale, is that Ruby makes you fuss over scaling right away.
Well, "right away" is kind of misleading. If you're the average company making a Rails website, you'll get by with common-sense optimizations, database indexes and the like that you'd have to do in PHP anyways. I've worked on probably a dozen Rails apps and have only ever had to resort to horizontal scaling and memcached once.
I think the key is that developing the app and scaling the app can be separate tasks. If you do it right, for the lion's share of your app code is still focused on the app, and all the caching and whatnot is handled elsewhere. In PHP, if you had to use memcached it would be a massive change that would touch every corner of your codebase. In Rails, you'd use a plugin and maybe a few filters and you'd be good to go.
I think that's a good description of the tradeoff. At some point, the filters, plugins, middleware and so on that let you focus your energies on the app begin to interact in non-trivial ways, and so the time you spent not having to worry about them during development gets repaid worrying about them in deployment.
That is silly. Why is adding memcached to a PHP app need to be a "massive change that would touch every corner of your codebase"?? Like any web app coded in any language, if it's properly layered, memcached can be added to an app (PHP or not) in a couple lines, sometimes as few as 1 line (ex. ADODB w/ memcached).
Except, the article demonstrates that worrying about scaling right away isn't really necessary (even though it demonstrates how to do so later):
Note that I did not use Mongrel, evented_mongrel, Thin, or anything else sophisticated as the container for the application. It was just webrick, and it was just a single instance of webrick [.. benchmark done here, gets ~35rps ..] OK. I mean, that’s not horrible. Redmine isn’t a lightweight app, and that’s over 2.5 million requests a day on a single process.
Of course, everyone's idea of scaling and what level of requests is reasonable is different, but there are plenty of sites turning over big bucks doing less than 35 requests a second.
Unoptimized Ruby can "do" on modern hardware - even if it's less than ideal. After all, back in the late 90s, even top sites were running on hardware 10-20x times slower than now. So even where Ruby is 10-20x slower than the alternatives, you can still get 1990s enterprise level performance out of it ;-)
I don't follow. Sinatra is light because it omits things. Rack is extremely light, too, lighter than Sinatra, but thats obviously because it omits even more things.
If I were to build the same Web site for the same audience and expected traffic using Rails and Sinatra, would using Sinatra (as compared to Rails) reduce the need for what the OP described regarding caching, load balancing, and other methods of increasing performance?
Perhaps it would, as would using Ramaze, or simply writing targeted Rack middleware, but the gains from using lighter tools such as these, as compared to Rails, is that you lose out on using many pre-existing libraries. And while Sinatra and Ramaze are faster than Rails I'm not so sure that they are so much faster that you'd see a big difference in trying to support heavy request loads.
That said I still approach Web apps with the intent of using Ramaze because of it being light, very fast, and feature-complete, but if I find that there are some requirements that are well-matched to some existing Rails extension I'll take that route.
Again, to an extent. If the site is simple enough to do it in Sinatra without too many dependencies, etc., then yes, it would _at least_ postpone performance optimizations.
My understanding is, however, that if the site is already simple, you may wind up not needing to do these improvements in Sinatra.
Half of the article can be reduced to saying that ruby is fast when you don't run it (e.g. through caching), and therefore ruby is fast. That's a fallacy.
... and if you only ever make one request, from one user, over and over and over again.
ab -n 10000 -c 1 -C '_redmine_session=9ec759408f1ae3c6f919e50baba5a3dc; path=/' http://127.0.0.1/
Requests per second: 2839.37 [#/sec] (mean)
Time per request: 0.352 [ms] (mean)
Time per request: 0.352 [ms] (mean, across all concurrent requests)
This is an extremely unrealistic workload. It's the best possible scenario for your caches. Yes, he says he was also browsing and editing the site at the same time, but that's still nothing like modeling the real effects of cache invalidation & overflow from many concurrently users.
Seriously... any real load test, IMHO, needs to stem from a capture and replay of live production traffic. Especially if it involves a cache somewhere.
Looks very much like, at 3k req/s, that request was cached somewhere (either disk/memory/proxy), which are exactly the kind of optimizations the user mentioned you need to think about. Given that you do need to tell Rails when to cache, it may be trivial, but you're still thinking about it.
I don't like this at all. "Scaling" usually refers to how easy it is to just add more hardware to the problem.
But the thing that really irks me is the discussion of caching reverse proxies and partial page caching. Those optimization techniques are language independent. While I came to the same conclusions about usually needing these with Ruby, I fully recognize that it's much slower at running complex application logic and doing in-memory operations than other languages like PHP, Java, and even Python.
Instead of arguing that Ruby isn't slow (because it is), I would have argued that the time to build and debug a Ruby app is less than it would have been using other languages. Extensive library support, an active user community, many great tutorials / code snippets, no need to compile, and a pretty flexible syntax make Ruby great for quick development. But let's not pretend we can have our Ruby cake and eat it too.
Do you have anything to back that up? An implementor of a PHP static compiler commented that the PHP runtime is horribly inefficient and is only able to appear fast in practice because the majority of the standard library is written in C. If you compare Ruby 1.9 to PHP on the Alioth tests at http://shootout.alioth.debian.org/u32/benchmark.php?test=all..., Ruby is very comparable in both memory and cPU usage and scores slightly higher overall, beating out PHP. MacRuby and Rubinius are eventually going to push Ruby performance even further, and right now JRuby already improves CPU performance over the standard runtime.
Rails as a framework may do some inefficient things, and I've heard that the next version of rails will address many of these inefficiencies, but as a language runtime Ruby isn't any sloppier performance-wise than PHP and might even already be better at this point.
1) "Ruby Scales, and It’s Fast" makes a point of talking about MRI not Yarv.
2) The fastest of those PHP programs relative to Ruby 1.9 (n-body and mandelbrot) don't seem to make any use of the PHP standard library - which undermines your "library is written in C" point.
3) If you look at the quad-core measurements you'll see PHP but you won't see Ruby 1.9 or MRI because (unlike PHP) no one has contributed Ruby programs that can make use of more than one processor.
If Ruby developers would stop trying to debunk the "Ruby and/or Rails doesn't scale" myth, I think the rest of us would forget there was ever an issue. Scaling a web app is language independent, and writing inefficient code is also language independent.
I can't see why he used a single webrick process for testing this. It's widely accepted that webrick should never be used in a production environment, so this is a somewhat unrealistic test.
I used it because it's slow. Because the speed of Redmine running on webrick isn't the point. The points are A) you can write some really fast stuff that runs in Ruby, and B) if you do some prudent things like think about how to use caching in front of your app, even a really slow app can effectively be very fast when viewed from the outside.
Rather, the trouble with Ruby (and Rails) is that you end up having to implement these optimizations much faster than with a lighter-weight setup (like PHP on top of a vanilla database, with no ORM).
Hence all the discussion about your "stack", middleware, load-balancing, front-end servers, merbs, mongrels, passengers, and all the bewildering variety of gems required for the care and feeding of a production app. Rails developers write about armoring their app with all this extra stuff in a way reminiscent of MMORPG players equipping a character for battle.
It's a legitimate trade-off, and many people seem comfortable making it. But posts like this sidestep the issue. It's not that Ruby can't scale, is that Ruby makes you fuss over scaling right away.