The vast majority of overhead in the rails app I work on is poorly build data models and poorly written queries. It makes no sense to talk about marginal gains of a few percent or a few ms per request when there are DB queries that take multiple seconds to complete.
In our case, a large part of that is due to the decision that someone made 5 or 6 years ago to store large amounts of data as serialized ruby hashes in the DB, rather than JSON (unsure if postgres supported it at the time), or simply as separate tables.
None of the poor performance of our codebase is down to Ruby itself. Most of it is due to features and data models being implemented with no thought for performance, a lot of which wasn't an issue when first written but as we've grown have become a constant thorn in our side (e.g. retrieving a multiple-MB serialized hash from the DB just to grab 3 values, then doing this 10 times in a request)
So yes, a language that's both faster and has less overhead in its ORM / DataMapper library definitely will help you.
The Heroku dynos I've tested with some years ago performed quite horribly. Only a proper Xeon server was able to achieve sub-100ms responses.
But hey, if Ruby improved in the meantime, cool.
I've always thought of it as the platform you use for running toy apps with maybe a couple of dozen users at most and a low load. It's incredibly quick and easy to get a Rails app running on Heroku, a couple of hours at most. But you pay (in dollars and performance) for this.
(Then again, they have them with Phoenix as well but to a lesser extent.)
In an unusual situation it is possible in PG to have a very large pg catalog if you have thousands of tables and schemas which is resolved at run-time because Rails resolves models and types through db introspection, and the types specicially are only loaded during runtime. But that would be very unusual. I'm working on solving this in Rails because this unusual sittuation is affecting us.
Still, I regularly chat with Rails devs and to have a MacBook Pro 2018 return responses in 150+ ms is alarming. But you might be right that it could be a N+1 query problem.
Even without those though, I've still seen Rails apps perform quite horribly. So 50/50 from me, you might be correct but I wouldn't entirely discount the option that Rails is still quite suboptimal in terms of performance, compared to many other frameworks.
Because a lot of web developers these days build applications and ORM's are great but make certain patterns convenient so it's really easy to code yourself into places that don't scale. Then people reach for various caching solutions rather than taking a step back and looking at what's actually executing.
I've seen just about every bad pattern you can imagine and it's not usually obvious because the code looks simple enough. Like that permission check in your controller is actually serializing 1000 ids and querying against them, or that .first doesn't have an index so you're sorting the whole table, and much worse than that.
"The default behavior is slow!"
"Don't use the default behavior?"
I am glad to see that there are much more reasonable Rails devs out there compared to some rather toxic individuals around in HN at least!
A lot of tech can be fine-tuned to be very performant. My point was (still is) that there exist technologies today that allow you to delay your scaling decisions much further in future, compared to what a stock Rails app (without any performance tuning) will.
The Ruby phosphophy seems to be lots of magic (in a good way) and in exchange you accept that details get lost behind the scenes and that it's only fast enough, but not truly fast.
Switching to a language that values speed with tools that have a different phosphophy can then make such a bug much more visible, due to the lack of behind the scenes magic.
There are two other alternative interpretations that I think are untrue however:
* "languages that value speed give you tools that expose more of the details and thus help you avoid adding defects in the first place" which I disagree with because (1) the average programmer will not understand what most low-level options actually do and (2) exposing more options is like trying to program with ones and zeros - at some point low-level abstractions don't scale well in a constantly evolving project
* "languages that value speed generally have fewer abstractions and thus make it easier to find bugs because there is less abstraction" which I think is untrue in projects of meaningful size. Macros are very common to find in languages like C and arguably as complex as metaprogramming in Ruby. Additionally Java is considered a relatively fast language and Java projects often have lots of abstraction
In my experience, even in "slow" languages, that type of thing is the predominant source of major performance problems, and the supposedly "slow" language would be perfectly adequate if you an stop shooting yourself in the foot (and if you can't, a faster language will not help you).
I'm sure there are extremely high-performance or high-scale points where language choice starts to matter more, but I'm also not surprised if Shopify is correct not to think they're there yet.