How I spent my summer vacation: making Rails 15 times faster
Roman Samoilov
Posted on November 14, 2023
Everyone knows Ruby is slow. But is that actually right?
Last summer, I started thinking about things I dislike about Rails. This is not something I usually think about, as Rails is one of my favourite technologies. Mostly because I think I’d end up with something very similar to Rails if I had to write my own framework.
Still, I wasn’t entirely happy with the changes made to the framework over the last few years. And with the ongoing issues like poor performance, I decided to think about what I would do differently.
Inspiration
One thing that has inspired me a lot is the talk Ryan Dahl gave at JSConf EU in 2018.
In that talk, Ryan, the creator of Node.js, talks about some of the mistakes he has made throughout the development of Node. He also talks about the fact that JavaScript today is almost another language compared to JavaScript from when Node.js was started.
He attempts to rethink the approach Node.js introduced and presents Deno.
Today, Deno is a mature project used by Slack and Github. But back in 2018, it was a barely working concept that nevertheless allowed Ryan to share his vision with the community.
I work as a Technical Lead and know that vision is key. This is something that caught me by surprise when I started leading teams - you don’t have to be the best developer on the team to lead. You don’t even have to be the biggest expert in the technology you work with. What matters most is knowing for a fact what needs to be done and how exactly this can be accomplished - a vision.
Vision
I spent last summer trying to shape my vision of modern web development with Ruby and defining principles to encompass in a new framework. A framework that would rethink some of the concepts we are all used to. And I have finally settled on the four points:
Rails-compatible API - there’s no need to invent a wheel because Rails’ public API is clean and easy to use. Creating something new would steepen the learning curve and result in people refusing to use the framework.
High performance - this point is the most controversial one. A popular belief in the Ruby world says, “We should use Ruby when we don’t need high performance and other technologies otherwise”. Unfortunately, this view naturally transforms into “we should use other technologies all the time”. An application likely won’t start working faster once you use a faster framework. However, a framework with less overhead would enable much easier and more effective scaling. And while Ruby is not the fastest language, it’s not as slow as it looks like when using Rails.
API-only - technologies like Hotwire are pretty exciting, but one part of building sustainable and reliable applications is using standard approaches. Using JavaScript to create Web UI is not only an industry standard but also an incredibly simple and fun way to build modern interactive applications.
Acceptance of modern Ruby - Ruby 3.0 with the support for non-blocking IO was released almost three years ago. Non-blocking IO is essential for every modern technology, and it’s a shame we still block an entire server thread while waiting on IO.
Result
These principles ended up being implemented in a project called rage-rb. With lean code, critical parts implemented in C, and async IO out of the box, it offers much greater performance than Rails while providing a similar API.
As much as my ultimate goal is to make it production-ready and get companies to use the framework, it is essentially a concept I’d like to use to share my vision with the community and find people who think the same.
I’ve got no illusions - Rails will be with us for a long time. But is there something that could be done better? Or maybe just differently? rage-rb is my take on answering these questions.
Inspired by Deno and built on top of Iodine, this is a Ruby web framework that is based on the following design principles:
Rails compatible API - Rails' API is clean, straightforward, and simply makes sense. It was one of the reasons why Rails was so successful in the past.
High performance - some think performance is not a major metric for a framework, but it's not true. Poor performance is a risk, and in today's world, companies refuse to use risky technologies.
API-only - the only technology we should be using to create web UI is JavaScript. Using native technologies is always the most flexible, scalable, and simple solution in the long run. Check out Vite if you don't know where to start.
Acceptance of modern Ruby - the framework includes a fiber scheduler, which means your code never blocks while waiting on IO.