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.
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.
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.
"The default behavior is slow!"
"Don't use the default behavior?"
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
There's a myriad of tools out there for profiling, some language specific, some not. Learn at least one of them well, how to read flamegraphs and how to benchmark properly (warmup code, synthetic vs real traffic, etc). There's definitely a jump between making guesses and hoping you improve performance vs truly understanding what your code is doing.
From what I understand, it's the fastest VM out there at the moment for Ruby.
And yes, it's from Oracle but they have GPL'd the code [2]
[2] https://www.graalvm.org/docs/faq/
Edit: looks like TruffleRuby is built onto of Graal.
Not sure when they clarified the licensing around GraalVM, but it's what kept me away from it since it's inception. Looks like the single executable binary is under the Oracle license side of the equation.
Meanwhile Ruby 2.6.5 chugs along and finishes the whole suite in 8 minutes. Never hitting any unreasonable amounts of memory.
Also our C extension emulation layer used to be extraordinarily slow while we made it work correctly, and it's still rather slow.
It's a challenge but we're working on it.
But TruffleRuby is the only alternative Ruby implementation to even run major applications that I've tried at Shopify.
def benchmark_time(repetitions = 100, &block) require 'benchmark' Benchmark.bm{ |b| b.report{ repetitions.times(&block) } } end
Ruby used to be able to say we sacrifice performance for developer productivity.
I don’t think this is any longer true, there’s plenty of languages out there that developers can be just as productive with, while producing wildly more performant code.
Also the Ruby/RoR community and culture is better than most other languages/framework. I think culture is a totally valid performance reason to pick a language. Sure there are faster languages and there are jerks everywhere but on average it seems RoR devs are on average nicer and more collaborative people relative to peers.
There is a just a mindset for wanting to write in a language optimized for developer happiness that dovetails with wanting to be happy and work happily with other people. Ya sure those C++ guys can write more performant code but I know who I want to work next to 8 hrs a day. And who I will be more productive working with.
Also I don't think there are plenty of languages that are Ruby/RoR peers. Django doesn't come close. JS ecosystem is a dumpster fire. Some functional and JVM languages maybe but they often come with a corporate culture that kills their benefits. Kotlin would be my bet I guess?
Also if scale is your issue and rails isn't cutting it then you need to go to a proven language with a proven and hirable developer base. That rules out a lot of new and promising languages. Sure they might be just as productive languages but they are resource constrained at the people level. It is really hard to hire Elixir/Phoenix devs etc. You need a talent pool of thousands. Also you need to KNOW the language will be there with a community in 10 years and that it has a history of evolving without screwing over the community. I guess Twitter going to Scala would be an example of this, from my understanding it doesn't solve all their problems.
Total aside: plenty of language need massive tuning to work at scale but it seems like Ruby is unfairly singled out if someone does "exotic" tuning of it but if someone tunes a JVM language or invent their own it is supported.
I don't think this is true at all. Where was Rails 10 years ago? It was pretty bad compared to today's Rails. If the Rails 2 and Rails 3 rewrites never happened then RoR likely would've been superseded by something else and be "dead" today. The point is that Stripe, Github, etc were all early adopters of Ruby and accepted that risk
> You need a talent pool of thousands
I also don't think this is true. You need to hire the right people and you need for them to stick around. And you need to be in the right line of business obviously. Again most of the companies you listed were small/passionate/scrappy for a long time
This has not been my experience.
It has been “do it THIS way in ruby” even though either way is perfectly valid (eg list of Literal strings / symbols vs %i or %w.
Lots of bike shedding type discussions on which way is better and unsurprisingly no consistency across the codebase.
There’s also a lot of hidden things you can only learn from years of usage and no clear documentation of when / where features came and went.
All in all every Ruby dev I’ve worked with across 4 companies have all had the same sort of elitist / pretentious attitude compared to Python, Go or Java devs. Ruby has only been second to Scala and Rust devs (so far).
There aren't that plenty really. Golang has nothing like Rails, neither does Node. You can say Django / Laravel but then it's the same performance issues. Or maybe you're talking good old enterprise software like Spring / Asp. I don't think Ruby/Rails should feel inferior to any of those names for web development.
The problem I have with JS (both for server side and client side) is that there's usually several different packages/libraries/frameworks to achieve the same goal, and often one gets deprecated in favour of another, requiring constant updates and changes to the development and build environment. JS development is all about the flavour of the week. For example gulp/grunt/webpack, or NPM/bower/yarn. This is compounded by the lack of a standard library.
Every company has its own particular build system (and configuration of that system), libraries they use, style guide, and file/folder layout. It's also very easy to abuse scoping and class mutability, with only style guides and eslint to save you. It can be a lot of work keeping a larger and older project up to date.
But I think writing new features, or rewriting some critical paths of the codebase in a new language could make sense.
It's atleast a valid question.
They are clearly already spending a lot of resources optimizing Ruby code to match their demands.
My question is at what point does continuing with Ruby become trying to force a round peg into a square hole?
I don't see why that would be the case. In fact, the performance improvements during the 2.x era seem to indicate the contrary: that Ruby can be faster.
Well, the extensive use of “method_missing” appears to be staggeringly difficult to optimize short of a tracing jit and it’s also the core idiom of many popular frameworks. Of course it can be faster—if you remove the slow, unique features you can optimize it like any other language.
That's an interesting note. They have a $90b market cap, trading at ~53 times sales. It's one of the more extreme valuations I've seen in the last 25 years, including the dotcom bubble (and that's saying something with how overvalued everything cloud-related is today).
As one comparison for the absurdity, Yahoo during most of the height of the dotcom bubble, was trading for 30-50 times sales, growing sales faster than Shopify, and they were solidly profitable (Shopify has never earned a consequential profit in its history). That's how bad Shopify's present valuation is, to get good comps you have to reach into the dotcom bubble.
The market thinks they're Amazon-like. The problem is they've never demonstrated any great margins in their platform (despite 14 years and counting) and Amazon's big lift-off in their stock occurred solely due to the ability of AWS to generate immense operating income. Without AWS, Amazon eventually gets the sad multiples of a Target or Walmart on their retail business.
This is an obviously mistaken valuation riding one of the most overvalued markets in US history, one that will most likely brutalize investors that get in late. It's a classic example of how very inefficient and irrational the stock market can be in the shorter term. And no, that doesn't mean an investor should be the fool to step in front of the irrationality train and short it either (everyone here probably has heard the Keynes line about the market remaining irrational longer than you can remain solvent).
It'll take at least 10-15 years at a minimum for Shopify to grow into its present valuation, in the best case scenario, if everything goes perfectly and they some day find some margin in their business. If they eventually manage an enormous $2 billion profit ($1.7b in sales today ttm), they'll still have a 45 PE ratio at today's valuation. That's a prime market example of insanity.
eBay has a vastly superior business (in all regards, including its quasi-monopoly positioning and the tremendous profitability of ebay's platform), trading for a huge discount to Shopify, on the basis of the market's mistaken extrapolation about Shopify's future. If they're lucky, they'll one day be the size of eBay with a fraction of the profit margin (and of course eBay has a mere $29b market cap, 12x op income multiple; compression is a killer). I mention eBay (beyond obvious reasons), because Shopify is likely doing nothing more than pulling future returns forward to an extreme, as eBay once did (leading to a decade of stagnation in the stock).
It fundamentally has to be slower. Ruby is the most dynamic of the dynamic programming languages. And the community has embraced metaprogramming, making it every more dynamic. Especially on webservers, you'll be executing hundreds, sometimes thousands, more lines of code than other servers, especially in a mature system.
Is it "slow" enough to matter? Probably not until you get to a medium scale. Everywhere I've worked, we've had to on average double the hardware specs for Ruby servers to make them as performant as other dynamic language applications we run. Not the most expensive thing in the grand scheme of things, but there are entire cottage industries of magically tuning Ruby and Rails that you don't have to worry about with other systems until much larger scales.
Also, I'll take "double the hardware specs" if it means I'm actually able to focus on what I'm building and not dicking around with devops or rebuilding all of stuff Rails metaprograms for me by hand.
If there was a framework for being as productive as Rails at half the cost then it would be flourishing. There isn't and as a result Rails isn't going anywhere any time soon.
Try 7x to 11x. That's the amount of reduced RAM usage -- and the amount of increased accommodated users -- on identical hosting by the two apps I rewrote from Rails to Phoenix.
> If there was a framework for being as productive as Rails at half the cost then it would be flourishing.
Bold of you to assume technical merit is the only factor. Historically this has almost never been true. There are a number of web frameworks that perform much better than Rails and are quite easy to work with.
Cargo culting is a powerful force. Corporate inertia -- even more.
Phew, I'm glad GitHub and Shopify's scale is still small.
I mean, every programmer who funnels through university understands map reduce, and that helps on multi-core threading up to system job running.
But there is a limit, usually in the persistence and caching layers. What you'll find is that those "large scale deployments" are going to have a -lot- of internal cache systems and I can pretty much guarantee that the services running those caches and persistence will not be written in ruby.
You can make anything* scale, but how many CPU cycles you need to burn to get the functionality you want is a matter for the finance department.
If you're running in a lossy business, you can bet that those CPU cycles will begin to cost more than developer velocity is worth, because servers are an eternal and ongoing cost.
On the flip side if you make more money than the infra+devs cost, then nobody is going to hound you for wasting 2x 3x the cost. Because "it's the cost of doing business" is easier to justify when you're cash positive.
Phew, good thing they can afford to burn a lot of cash for hosting.
additionally: > Sinatra + Sequel is already very competitive in web performance with Go > Between Ruby 1.8 and 2.5, performance has improved around 13x in tight loops[2]. The Rails performance issue has been massively overblown since 1.9 was released.
A lot of the time, that "competitive with X" in web frameworks is because the scripting language has a web server coded in something other than the scripting language. I don't know about that exact stack, but I know that's the case for Node, for instance. The web server is written in C. So when you benchmark a "tight loop" in those languages, you are running 99% C and 1% your scripting language.
Now, that is not a bad thing. It is a valid result, in the sense that it is a good thing for environments to have fast web servers, and nobody cares what the implementation language is... with perhaps the sole exception of this case, where we're trying to compare the performance of scripting languages by their web server implementation. You can't claim "Scripting Language X is fast because it has a fast webserver!" when the webserver isn't written in Scripting Language X.
(A moment's perusal didn't show me what this particular web server is implemented in. If someone can link me to that web server and show it's implemented in Ruby, I'll be happy to eat my words here. But if the performance is comparable to Go, that's enough evidence it isn't written in Ruby to satisfy me until more evidence comes in. If Ruby isn't a slow language, you've defined "slow language" to the point that no language is slow. There isn't much competition in the "slower than Ruby" field; Perl 6 is pretty much the only entrant I know of. There's a number of languages as slow as Ruby, it is not uniquely slow, but there's almost nothing slower.)
Phoenix is written in Elixir -- another dynamic language.
I am willing to argue with facts but you just added another non-factual opinion to the pile.
...Oh, and a Mario game implementation says nothing about the typical production uses of a language and its stack.
That, plus the fact that most Ruby users don't go for Sinatra and Sequel.
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
And I am pretty sure backwards compatibility will continue dragging JS down for quite a long time still as well.
If it doesn't bring you that, then we have a problem!
No & No.
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
Shopify's investing in TruffleRuby as well as MRI - they employ me to work on it. We have it able to run one major app, but still working on making it as fast as we'd like.
Includes some rare, bonus ruby implementations too <3
It's that easy :)
I've lately been writing several Rust tools and mini apps and have admitted to myself that even if a language stack clicks with you almost perfectly, you should still reach out to other tools when appropriate.
Even us the senior devs forget that, and it pays to get reminded of it every now and then.
It's quite amazing the lengths the companies will go to just to avoid changing their status quo. But for them it makes sense.
---
EDIT: Downvoters, calm down. Ruby on Rails is objectively quite a slow framework and this is proven in many public benchmarks (Techempower included). And Ruby isn't the fastest among the dynamic languages either.
Less cargo culting and more facts, please.
Then people go on all sorts of crazy journeys to justify their investments in pain and burned money.
Even though I get downvoted at places in this thread (and upvoted generously on others), I will never tell to people "you should always just rewrite to Elixir". Meh. If your app works fine, have it be in COBOL or PL/1 if that helps you do your job better.
But as you said, when your app/hosting starts struggling you should start rethinking your choices if all the lower-hanging fruit has been already collected.