Ruby 3 JIT can make Rails faster
k0kubun.medium.com
k0kubun.medium.com
JIT only adds a marginal improvement to this current setup.
A true async backend like Falcon adds a huge amount of concurrent throughput if tuned correctly and ractors could provide a big parallelism boost if they shared more memory.
In the context of developer productivity it is also pointless to talk about high performance because people sacrifice performance for developer happiness.
Once you understand that you have these two dimensions most frameworks are revolving around it is getting much clearer which one to pick for a certain use case.
It is true that spending time optimizing queries will give you more benefits than JIT though. CPU is not the bottleneck for most Web tasks.
Btw. I haven't seen Rails or Ruby on this list in the top 50% for a while:
https://www.techempower.com/benchmarks/
I would prefer hard data as opposed to "this is a legend".
UPDATE:
Rails is number 399 out of 439, having 0.3% performance of the top frameworks in a plain text task.
I know, facts hurt.
While it's true Rails will use more ram than other options for a given traffic level, many of us have scaled it just fine.
The techempower benchmarks aren't particularly useful for anything other than forum warrior style arguments. They don't really measure a realistic workload.
Your last sentence is entirely unnecessary.
Everything I said is factual. Many of us have built successful startups on rails. I'm a very pragmatic person in general and abhor the cheering and jeering dynamic you're actively courting in this thread.
Your concerns are further diminished ~ every two years. Please re-evaluate your assumptions on that timeline.
This position was established by the company that owns the one of the largest server farms in the world? Are they looking to save on a few x-large instances? Seems short-sighted to me.
Sub 50ms response times are very achievable with Rails.
Throwing another server at it is a very reasonable response. Especially when you want your team to remain productive in a cohesive, batteries included framework.
Plenty of real-world Rails examples to demonstrate this.
The fact that it is being used at Shopify and Github doesn't make Ruby Rails Fast. It just means their Business Model fits its usage COGS. Especially true if you are a SaaS with low / no Free Tier or Non-Freemium model.
Now that Shopify are spending hundred millions on cloud it absolutely make sense for them speed up Ruby Rails. I just hope it wont end up being like Twitter.
https://mobile.twitter.com/brandonhilkert/status/13973190133...
Even a single n+1 query can really hose performance by burdening the entire database.
ORMs can be bad, but it's not fair to blame them "just because".
I agree knowing SQL is very important, even if you use an ORM, sometimes you might need to roll up your sleeves and write some SQL (not to even mention knowing how to EXPLAIN queries, use indexes, etc).
Nowadays most things are abstracted away. A similar thing happens with IDEs, if your IDE takes care of compiling and building everything for you, then you don't understand how everything works under the hood. Is that a bad thing? It depends.
If you show HTML to a junior JS dev he'll say it's React, lol. I think there's no way escaping the abstractions in modern times.
At least there are tools to warn you about n+1 automatically https://github.com/flyerhzm/bullet
Yes, it is crazy inefficient.
At Wunderlist, we launched WL3 with something like 1K rails boxes on AWS, running a few services. During the launch, my fun was tracking when we reached user/box parity :-)
But it did work.
After a while, we replaced each of the hundred+ rails boxes per service with 2 Scala instances per service.
Also worked. No change for users.
The FP folks should be forever grateful to Ruby for making their languages seem fast in comparison.
At another company where I consulted, for a web content management system, the rails devs were super excited to get the performance up to slightly below one second per request.
We got much better than that 2 decades earlier, running a CGI-Bin (no fast-cgi, so complete restart on every request) that completely re-initalised its Oracle DB connection every time etc. On hardware that was a small fraction of the performance of today's boxes.
If you had 20 instances, that is under 2 requests per second per instance.
I don't know what each request does of course, but it might be worth asking if each one should really take a billion clock cycles to complete.
If that was the case then Rails was their least important problem.
At the prototyping stage back-and-forth with the client I write VERY rudimentary Rails code, n+1s be damned, but I don't remember ever seeing a second long request.
GitHub runs the vast majority of web requests through a giant Rails monolith; and they're not alone. I think calling it "impossible [to] scale above a certain (very low) threshold" is an uninformed opinion (and not supported by the evidence), to say the least.
TIL also that in Rails v5+, `config.allow_concurrency` is enabled by default, so Falcon works with it out of the box. Neat.
Looks like Falcon's [benchmarks](https://github.com/socketry/falcon-benchmark#results) show 250+ concurrent connections serve with an order of magnitude less latency and 2-3x the RPS of puma or passenger, and >10x that of unicorn.
Seems worth a look for anyone running Ruby in prod with really any concurrent traffic.
The better graph to look at is the “Blocking Benchmark”, which shows all backends performing (equally) poorly.
On this topic, a warning for anyone trying to implement async rails with postgres: beware. Connections are per-thread in the ‘pg’ gem (and every other driver I’ve used), so one client’s connection may commit/abort another client’s transaction, and they end up stomping all over each other. Which you will only observe under load.
There’s an eventmachine-based driver for postgres but it’s almost completely unmaintained afaict, and doesn’t work with any new rails versions.
I spent a ton of effort migrating an internal rails app to eventmachine, only to realize at the very end that it fundamentally doesn’t work with typical CRUD/database apps.
(Note, this experience was probably 4 or so years ago at this point, things may have matured since then, but I’d still say approach async rails with extreme caution.)
Non-blocking MariaDB https://github.com/socketry/db-mariadb
Rails v4+ :)
Also, you need to use a thread-based app server like puma. App servers like unicorn do one process per request rather than threading.
Likewise, async IO has high throughout but often trades that off for increased latency jitter, since requests can block each other because of the limited thread pool. This is less a problem with threads because of preemption (though they of course compete for shared resources like database time).
> This is less a problem with threads because of preemption (though they of course compete for shared resources like database time).
eh, just because ONE implementation of async is single threaded, does not mean that others aren't.
basically you trade of latency because most async implementations do SCHEDULE their tasks/promises in a WORK STEALING fashion (overscheduling and stuff) and another tradeoff is context switching, of course not all task implementations try to reduce that. also if you have blocking operations it might happen that you have two tasks/promises on the same thread, which are lightweight at the beginning and at the end the blocking operation might block the other promise (thus latency for b is reduced)
with threads you MIGHT have higher latency in p50, but probably not in p99. of course if you have 16 threads and only 16 requests at any time, the sync engine wins, but most often that is only the case in small applications with few users.
In my experience even with a JIT Rails is spending a lot of time in all the layers of request processing, so it has limited throughout even when the actual IO is trivial. No async framework can save you from processing overhead like that.
Note: I work on TruffleRuby and Project Loom.
My point is, you can't generalise "what rails needs". Different deployments will need different things.
At the same time, fiber-based concurrency does look promising for lighter weight Ruby web stacks.
MIR, coming from Vladimir Makarov ( RedHat ) again.
YJIT coming from Shopify, Dr Maxime Chevalier-Boisvert is leading the team and Dr Stefan Marr ( I think ) will be joining them soon.
TruffleRuby, with Dr Chris Seaton now also working in Shopify.
JRuby, Charles Nutter ( RedHat ).
Maybe everyone should be porting to V8.
Are you taking into account JVM warmup time ? Also does the JVM have adequate memory (thinking of GC thrashing)?
I don't know if there's any real world node application that is faster on GraalJS, no matter how much "warming up." It is incredibly slow. I understand there's marketing copy out there saying stuff to the contrary, but really, if it was that great, people would be using it. Which I'm confident people don't, because real world applications use tons of the node API that Graal doesn't support, like `setTimeout`.
However, David Heinemeier Hansson, co-founder of Basecamp and creator or Ruby-on-Rails, has this interesting take on the cost of running Ruby for their business. Make of it what you will:
Only 15% of the Basecamp operations budget is spent on Ruby (2019)
https://m.signalvnoise.com/only-15-of-the-basecamp-operation...
It's also really great to see large companies like Shopify invest in such low-level things, and not just on gems/changes that directly touch their business.
It's not clear that's true (as in yes you'd probably still need all of those things at a high level, but would you need as much of them and would you need them out of process on another machine?). If magically your programming language gave you enough performance that a single binary + SQLite served all your needs and stuff like caches, message buses, and the like were completely unnecessary that'd radically change your ops budget.
Of course that is truly magical, but then again there are quite a lot of papers that demonstrate well-crafted single binary services outperforming heterogenous complex clusters with orders of magnitude more compute resources.
But again, it only works for specific type of Web Apps. Those that require lots of traffic to generate relatively smaller amount of revenue, running on Freemium model wouldn't work because your cost / user are far higher. And these Web Apps / Site power 90% of the internet.