> What kind of speedup is available for big Rails applications? If 90% of the time in an application is spent in database calls, then there’s little opportunity for improvement via JIT technologies.<p>This is written as speculation of course, but it matches some long-time "conventional wisdom", that most Rails apps spend most of their time on I/O waiting for something external.<p>That may have been true once, but i don't believe it's true anymore.<p>My Rails apps now, when things like "n+1 database query problems" are properly eliminated, all spend more of their time on CPU than I/O, 60-80%. (I think most of that CPU time is ActionView rendering. Unsure about CPU parts of ActiveRecord, that aren't waiting on DB, but converting db results to in-memory AR objects etc).<p>When this comes up and I ask around on social media who else has actually looked at their app and can confirm or deny, almost all who respond agree. I would be curious to see here too.<p>Definitely some more systematic rather than anecdotal investigation is called for. But I think it's time to stop repeating that it's likely that a Rails app is I/O-bound rather than CPU-bound, my experience leads me to think the reverse is currently likely.<p>[*edit* after I wrote this comment, I noticed <i>multiple</i> other comments in this thread saying basically the same thing. OK, so. Can we put this rumor to rest?]
After almost 4 years, I recently started working on a small Rails app. Typical Rails responses used to take hundreds of milliseconds before, now it takes tens of milliseconds (with latest versions). I was not expecting that at all. Together with turbo and stimulus, responses seem almost instant. Kudos to the Ruby and Rails teams.<p>I am definitely excited about Ruby/Rails again!
> If 90% of the time in an application is spent in database calls<p>This is what a lot of people say, but I'm not sure that this is the case.<p>I think apps spend about 50-70% of their time in compute in the interpreter, at the low end.<p>People don't often make metrics from their apps public, but here's one example from a web site that renders text - so it's reading from the database and not doing some unusually computational task with the result <a href="https://genius.com/James-somers-herokus-ugly-secret-annotated" rel="nofollow">https://genius.com/James-somers-herokus-ugly-secret-annotate...</a>.
>What kind of speedup is available for big Rails applications? If 90% of the time in an application is spent in database calls, then there’s little opportunity for improvement via JIT technologies.<p>This has always been the premise for enabling multi-threading on RoR applications despite the GIL. The convertional wisdom is you spend 80-90% of time waiting for the DB and other IO. After 15 years of hosting rails applications, I'm pretty sure that is not generally true for real world applications.<p>It depends on the application obviously how this works out, but for a larger, complex saas app I work on it works out to 64% ruby time for web requests. For another application, that does a lot more external calls, it's 52%.<p>So raw performance of ruby can have a pretty significant impact on real performance for RoR applications. To the point where a faster CPU (new gen on AWS) improved response times by 15-20% for us.
I would summarize the article as:<p>- Ruby would benefit from object shapes and JIT compiling<p>- Good news, both of those are being added / improved<p>- The jury is out about C extensions<p>I hope ruby has a renaissance in the next few years. People can and will howl about its performance, but it’s <i>far</i> faster than it was even a few years ago, let alone 10. The changes mentioned in the article, the async gem, and ractors are all exciting things that could push it even faster and unlock previously unavailable design patterns.<p>Byte for byte, it’s one of the nicest languages (in my opinion of course), and for many use-cases Rails is like having developer superpowers.<p>I hope renewed excitement leads to more investment from folks, because it’s honestly just such a nice, ergonomic ecosystem to use.
Since several people are chiming in with suggestions for what might make rails slow I will throw in my two pence.<p>Profile things, and make sure you understand the results of the profile (because profilers can lie to you in a whole variety of ways).<p>When I last checked on TruffleRuby some time ago the slowest thing on a small rails app was all the layers of framework and all the points at which it might log things, while the actual database access and the use of that data was pretty quick.<p>This might not continue to be true for larger applications, but it probably means there is a high minimum amount of work that must be done per request, and it’s so deep on the stack that it’s unlikely to be optimised away.<p>The situation may have improved, we’ve done a lot of work on TruffleRuby since then and completely changed the inlining strategy at least once, and the method lookup and dispatch. But the profiler has also changed significantly so the way it lies will also be different now.
I think implementing shapes is very likely to significantly improve the raw compute speed of Ruby applications.<p>That said, if you're implementing an application in Rails, there are a number of low-hanging fruit that will significantly improve performance. In most cases they'd apply in <i>any</i> language, but since it's trivial to get "something running" in Rails, it's easy to forget the basics for performance. E.g.:<p>* Index your database for all queries that matter.<p>* Use caches. In the case of Rails, use partials; they are <i>amazingly</i> effective at improving performance.<p>* Use a tool to detect N+1 queries, and fix them.<p>* When querying with an ORM (ActiveRecord in Rails), request just the specific fields you need instead of "downloading everything" into the object. Getting unnecessary fields increases the database response, the memory use, and the garbage collection effort, and all of that unnecessary work eventually adds up.<p>In general, you can get a lot of performance improvements by doing only what needs to be done and nothing else. Caching to avoid repeated work, requesting only the data you need, etc., can provide a lot of performance improvement and often require relatively little effort.
> If 90% of the time in an application is spent in database calls, then there’s little opportunity for improvement via JIT technologies.<p>Even if it is true (for a given application) it doesn't mean that you don't need to optimize CPU usage. It's just mean that you may run out of RAM first (if you don't use async I/O) before you'll saturate CPU. Or may not.<p>First, in most non small projects database and app (e. g. Ruby) layers usually either use separate hardware or shared HW but we can account hardware cost for each of them. If DB layer uses much more HW than app layer then yes, it makes little sense to reduce CPU usage by Ruby. But usually an app layer is bigger, especially if a language like Ruby is used. Let's focus on the app layer assuming our DB layer works well (request latency can be non negligible - if it is stable under any load we have - that's fine). Assume we need N servers with Ruby - let's look what prevents us from using N/2 servers and saving money: for web apps it is either CPU or RAM (disk I/O handled by DB layers, 10Gbit network bandwidth should not be a bottleneck in most cases). For contemporary server hardware and web apps in my experience it is more common to saturate CPU before you'll run out of RAM so by reducing CPU usage you can save money. But your mileage may vary.
I love Ruby so much as a scripting language, I ask myself why I don't just use it as an "acceptable lisp" [1] for my research, rather than Haskell. Haskell is more easily parallelized than any other language I've experienced. Alas, my experiments with Ruby 3.1 parallel extensions flunked. Who cares about single core speed?<p>I was always put off by Rust syntax (it's a fly-pollinated flower, to attract C programmers), but I'm starting to get the genius in its machine model. Learning Rust forces one to understand what's happening at the machine level, but offers better control as a reward. Its expressiveness is a lot closer to Ruby than I had imagined, it won't put me back in the C99 stone ages. So my provisional answer is that Rust is a Faster Ruby.<p>[1] <a href="http://www.randomhacks.net/2005/12/03/why-ruby-is-an-acceptable-lisp/" rel="nofollow">http://www.randomhacks.net/2005/12/03/why-ruby-is-an-accepta...</a>
I think that one underrated point about web apps performance is JSON serialization for non-JS languages. JavaScript is obviously fast with that, but non-JS languages exposing API, like Rails in a separated FE/BE architecture, spend much time transforming data into JSON, and it doesn't seem stressed enough to me.
Another thing though: If at least one of your constraints are speed, a dynamically language probably shouldn’t be your first choice. If you need to maintain memory safety, Java or Rust would be more applicable.<p>That being said, once you have a codebase written in a certain language, you might just be stuck there due to hired talent being familiar with it. I don’t think I’ve really seen a company pull off a polygot move cheaply. Instead, a parallel move to something like Crystal may require minimal re-training.<p>… just thoughts I would have if I were in charge of investing R&D time at a large org like the ones mentioned in the article.
> What kind of speedup is available for big Rails applications?<p>When working with both ActiveRecord and Mongoid, I noticed that the vast majority of time spent outside of the database is in runtime type-checking and type conversion. That is, when an object is passed in from the DB, it takes the model a bit of time to get all of the data set up correctly. This doesn't become a huge problem unless you have a lot of embedded data in the record, which tends to happen more frequently in MongoDB.
Somewhat related, what do people think of Crystal (a compiled language with types with Ruby-like syntax)? How is it for web applications? Is there a Rails equivalent for it yet?
“Just throw a compiler at it!”<p>If you really want a speed bump then that’s exactly what you want to do. And I think Ruby’s overlooking a golden opportunity to join forces with Crystal.