Hi, I shared some of your thoughts when I read that other article, but I actually find Nate’s article more aligned with what I think than this article. Let me explain.
First of all, I’m no longer using Rails, but Roda in the application I maintain, but performance was definitely not the reason why we moved to Roda.
So, basically, I agree with you when you say that the main issue with Rails (or Ruby web development in general — more on that later) is hosting costs when compared to other less resources intensive solutions. On the other side, I do also agree with Nate that for several companies those savings won’t be significant, and can even be more expensive if it slow down the development activities. We had similar discussions a few years ago when people used to deploy with Unicorn and people were arguing that deploying with Puma would be cheaper and they were right for most scenarios.
I still think that the main problem with Ruby is that there are basically two alternative implementations that people are actually using widespread. MRI is by far the most popular, but it doesn’t support real multi-threading due to the GVL, which means that some applications will need to spawn many processes in a Puma cluster, for example, in order to use all available cores, which means much more RAM, and RAM is still expensive to these days.
The other popular Ruby implementation is JRuby, but it’s a Java process which means it also has high RAM footprint, it takes longer to boot (which is specially important during the application development) and it’s always behind the specs so you have to wait until you can use that last great new feature introduced in MRI. Also, it could be incompatible with quite some popular gems, specially those relying on forking and spawning new processes.
So, until MRI provides a real GVL-free multi-threading model, it’s hard to demonstrate that Ruby can perform almost as well as any other high-performance languages for practical purposes using about the same resources.
I second Nate in thinking that 100ms isn’t usually a big deal when DNS look-up can take longer than that, total bandwidth transfer will often take more than that and so on. The performance of my application is about the same as it was when we used Rails. NewRelic says something around 20ms as the mean, but it doesn’t provide me percentiles out of the box unfortunately. Of course some actions will take much longer than that, like exporting tons of data to Excel for example. And I agree with you that those numbers just don’t matter out of context. There’s often a critical path that matters and should be optimized and many others that don’t really matter. And it’s often possible for those that matter to process them in a separate less expensive infra-structure, you don’t need to be tied to Rails or Ruby.
I also agree with others that commented here saying that ActiveRecord may well be one of the reasons why it’s slow. I’m not sure because we didn’t use ActiveRecord but Sequel in this application, so I can’t really compare, but I suspect ActiveRecord is way more expensive than Sequel to instantiate objects. So, it’s hard to talk about Rails generally. What exactly is Rails? Is ActiveRecord Rails? We didn’t use ActiveRecord but we relied on railties, so I’d consider our application as a Rails one before we moved to Roda.
Also, maybe the views could be more expensive in Rails than in other light-weighter alternatives, but it provides out-of-the box escaping to prevent against HTML injection for example, and I’m not sure about the alternatives. Also I’m not sure about the views because our application is an SPA with just a handful of server-side views while almost all requests rendered JSON using vanilla Ruby JSON library to serialize the response. And I can tell you it’s fast enough for most real-world scenario.
I do also agree with you that many (most?) Rails developers don’t care enough about their dependencies and find it easier to simply put more gems into the application which adds up to the required RAM. However, since I started using Ruby in 2007, 10 years ago, no one was using Rails by that time in scale. The few that were working with Ruby were really smart, so you would expect any application they were developing would be awesome. This is how I see Elixir today. I guess the developers using Elixir these days are pretty smart, which doesn’t mean all the smart people are using Elixir. So, you’d expect applications written in Elixir today to be great ones. Not because it’s written in Elixir, but because it’s being written by smart people.
Ruby is now used by the mean programmer, which means you’ll find less than good applications written in Ruby these days when compared to 2007, for example. But the main problem remains the same. It’s all about architectures, about knowing the constraints and working around them.
Finally, I really agree with what DHH has to say about the subject. It’s not about performance or scalability or costs most of the times. It’s about taste. You seem to like Elixir, so you want to convince people that performance really matters because “Elixir applications are 10 times faster than Ruby ones”, which is clearly untrue whatever any other languages you compare. No regular web application written in X will be 10 times faster than another written in Y because of the language. Suppose Ruby would be the slowest language and suppose Ruby (or Rails) takes 10ms processing a request while IO would be responsible for 50ms. So, if you get the fastest possible language it will allow you to save at most 10ms, which means the server-side time would be decreased to 5/6 of the same time spent in a Rails application. When you add more 300ms of latency+bandwidth + SSL handshake and so on, that means the fastest language/framework would deliver the request 3% faster, not 10 times faster. But more importantly than that, you only saved 10ms which makes absolutely no difference to the final client.
I think this is Nate’s point in his article which you still seem to fail to understand. I think it is perfectly valid to try to compare exclusively the costs with hosting and salaries when you adopt some language, but it doesn’t makes sense at all for regular web applications to try to compare the raw language performance because it doesn’t make any difference if both applications would use a proper architecture. When we rewrite an application in another language we’re not usually just rewriting the same logic in a different language. We’re taking the chance to learn with our mistakes and also designing a better architecture. That was one of the reasons why our application got faster when we moved from Grails to Rails long ago, for example.
Very often people will adopt a language or framework for the simple reason that they like it. They will often argue that there are many technical reasons for that, but in most cases they don’t really care about them, they just don’t want to admit that they want to move to stack Y because they like it. And there’s nothing wrong with it. You don’t have to justify every bit of software in your stack, otherwise you’ll spend much more time searching for the perfect solution for a given problem than actually delivering value to the company, which is all that matter in the end.