We’ve been using Elixir for the past 24 months, and I thought it would be a good idea to write down my thoughts on Elixir vs Ruby and why our engineering team decided to stop programming with Ruby altogether and put all of our efforts behind Elixir.
Ruby wasn’t always a popular or mainstream language, but it did gain more popularity with the creation of Ruby on Rails by David Heinemeier Hansson (a fellow Chicago resident) in 2005. We used Rails as our primary web application framework for quite a bit.
When Elixir grew in popularity, we were quickly dazzled by its uncanny resemblance to Ruby, the language we already loved and cared about. The more we learned about Elixir, the more we understood its strength over Ruby and how it could tremendously benefit our business.
Fast-forward to present day, and the Elixir vs Ruby debate has been solved. We have switched completely to Elixir and thought it was one of the most important and best decisions we have made for our business.
The creator of Elixir, José Valim, was actually a Ruby developer himself.
So the first language I became really proficient in, really confident with, was Ruby. What I really liked about Ruby was this ability to explore, because the language is unrestricted and you can try out different things. And it’s very flexible—you can change it in many different ways. That was really what attracted me to Ruby at the time. [src]
José loved Ruby so much that in the earliest version of Elixir, he experimented with running Ruby in Erlang virtual machine! At the time, he was frustrated with inconsistent behaviors when running Ruby on multi-core machines. Concurrency was a very hard problem to solve in object-oriented programming languages, and José was not the first one to discover this.
However, he realized that in functional programming languages such as Erlang, the problem doesn’t even exist in the first place. This sort of lateral thinking opened up the path to solving many kinds of issues inherent with Ruby, such as background processing, long-running tasks, and process monitoring; while also incorporating the strengths and features from other programming languages such as Clojure, Haskell, and Python.
In the words of the man himself:
You can find a solution to the problem, but if you can make the problem disappear altogether, then, yeah, I’ll take that.
Most importantly, Elixir was designed with programmer happiness in mind, stealing Ruby’s main selling point. Elixir is growing as a mature language and should be acceptable for a demanding Ruby programmer.
Here is why I think Elixir is better than Ruby, and why you should choose Elixir as your primary programming language of choice. But first, let’s talk about what Elixir is exactly.
Table of Contents
So what is Elixir exactly?
Elixir is a functional, concurrent, general-purpose programming language that runs on the BEAM virtual machine (Erlang's VM). It is an excellent choice for any situation where performance, productivity, and scalability are top priorities, especially web applications and IoT development projects.
Elixir runs on BEAM, known for running low-latency, distributed, and fault-tolerant systems, while also being successfully used in web development and embedded software domain.
Erlang was created in 1986 by the Ericsson company to deal with the increasing demand for processing power within the telecom industry. It was designed to handle thousands of phone calls in a single PABX.
Erlang was released as free and open-source software in 1998. Although Erlang has remained an obscure language for most of its existence, its popularity is growing due to the demand for concurrent services (which I’ll explain in a bit). Erlang is also used in massively multiplayer online role-playing game servers, mainly because of the performance and scale that Erlang offers.
Cisco also said that 90% of the internet goes through Erlang-controlled nodes.
For context, Foxbox is a digital agency that builds mobile and web applications.
The companies we work with often come with user bases that are large enough to run into serious scaling and performance issues. Our engineers are exposed to almost all imaginable engineering problems you would probably come across at any stage of a typical tech startup. So, choosing the right programming language is not just important to guarantee the success of our clients, but also the survival of our business!
With that in mind, here’s why we found Elixir to be better for our business than Ruby:
- Development Velocity
- Safety and Correctness
- Hiring Quality
Let’s dive into each of these.
1. Development Velocity
Let’s be honest—we are excited about Elixir’s effortless handling of concurrency, but it’s not the main reason we stick with it. Elixir is a highly-productive language. Here are some reasons for that claim:
- Simplified development setup — Utilizing the BEAM virtual machine, one can expect to have a consistent development experience on almost any machine—even Windows. While this can also be true for Ruby, as a project progresses, a typical web application in Ruby accumulates more dependencies that make it increasingly difficult to get it up and running, while an Elixir web application would remain relatively easy to set up.
- Predictable codebase — Elixir enforces true lexical scoping and encourages explicit codes. What this means at the code level is that Elixir makes data transformations, code organizations, and application interfaces much more predictable and easier to reason with—thus saving a lot of development time.
- Lightweight and fast testing — This is probably the most undermentioned, yet most powerful, benefit of using Elixir. Elixir provides developers access to super-fast, concurrent testing with relatively minimal impact on hardware performance. Ruby testing, on the other hand, can be painfully slow and hardware-intensive—to the point that it could bog down the whole system for those with underperforming machines. Elixir completely takes away the headache by making tests faster.
- Useful built-in features — We have used Elixir to build a quick MVP project to building large-scale projects. In both scenarios, Elixir provides powerful built-in features to satisfy the requirements for a typical modern web application such as caching, background processing, and process monitoring. On a platform such as Ruby on Rails, these solutions usually come with tightly-coupled dependencies on services such as Redis, Resque, and Foreman.
I will admit, at first, I was extremely frustrated with Elixir. I struggled with pattern matching, which was touted as this revolutionary new concept. After getting used to it, and all of the other advantages of Elixir, I have found myself coding with less effort and frustration to achieve the same exact output as Ruby. There are two reasons for this.
It’s a functional language
Functional languages, as opposed to object-oriented languages like Ruby, are “beautiful” and simplify programming. I greatly favor functional languages for several reasons:
It leads to coding faster and more predictably.
No state to keep track of! State makes it extremely difficult to track down problems. There are no reference errors. Everything is a pure function, which is wonderful.
It has pattern matching
One of the biggest advantages and differentiators of Elixir is pattern matching. Pattern matching comes from its Erlang roots and is one of those things you wish was also incorporated into other languages.
One of our very talented engineers put together a code sample comparison between Elixir and Ruby using a simple ranking example.
Source: Fernando Schuindt, GitHub__
In that example, pattern matching makes the code more elegant, expressive, and easier to read. It may seem like a small thing, but I find myself using pattern matching any chance I get.
2. Safety Features Result in Fewer Bugs
Programming is a mixture of fun and frustration. I find Elixir to be slightly more fun and a lot less frustrating than Ruby. Elixir, a dynamically-typed language, has type-safe and guards built-in, along with pattern matching, which significantly reduces the bugs.
This results in fewer compiler errors. And for the bugs that do exist, they are easier to find because of the compiler. Compiled code is a huge safety feature. In Ruby, bugs can remain hidden until someone hits them; in Elixir, the compiler will find most of them.
Safety → Fewer Bugs → Easier to Track Down Bugs → More Fun → Happier Team → Happier Me.
3. It’s Fast, Real Fast
Elixir compiles into BEAM bytecode, so it inherits all the performance benefits of Erlang with almost zero penalties. On the other side, Ruby requires an interpreter that reads its code line-by-line during runtime. While choosing the right kind of production-ready Ruby interpreter for your application is already an uphill task by itself, squeezing more performance out of Ruby often requires strict adherence to Ruby’s do’s and don’ts. Want to concatenate strings? Sure. Want to make it run faster? Use string interpolation instead!
Elixir liberates programmers from having to carefully craft their codes based on an endless list of “best practices” for the sake of making their codes run just a tiny bit faster, and focuses more on producing codes that satisfy the needs of your business.
To be fair, Elixir may also have a similarly long list of performance best practices, but they come at a much later stage of development. Moreover, since Elixir is a compiled language, most performance issues can be caught by the compiler automatically, reducing the time and effort to write efficient, performant code.
Easy concurrent programming
Remember how I said Elixir was fun? Well, the way concurrency is handled in Elixir is one of the reasons I don’t see myself programming in other languages (unless I absolutely need to).
If you’ve ever had to deal with concurrency, you can understand how frustrating it is. The same program can generate different results if not handled correctly. You have to deal with locking, race conditions, and bugs that are difficult to solve.
The beautiful part of Elixir is that concurrent libraries are built into the language. You won't need third-party dependencies to achieve scalable, safe, concurrent programming.
These two reasons are a HUGE selling point for Elixir.
Easy to process data at scale
Cheaper to run: achieve more with less hardware
Ruby applications take up a lot of memory on a server because you have to run many instances of that app to handle multiple requests. Why? Ruby is effectively single-threaded because it has something called the Global Interpreter Lock (GIL) that enforces only one thread run at a time.
Elixir applications can handle magnitudes more requests per instance because it's concurrent and compiled (much quicker execution time). You can run a single instance of an Elixir application on a server to handle a huge number of requests. That lowers your memory utilization considerably.
When it comes to data processing, both Elixir and Ruby are considered expensive solutions in terms of memory compared to languages such as C, Rust, and Go. But in the world of concurrent data processing, Elixir and Erlang have a robust pre-built infrastructure.
With the smaller door (Ruby), you’ll have to wait longer for people in front of you to get in. On a wider door (Elixir), more people can get in at the same time.
Elixir handles concurrency in a really efficient way, allowing for more concurrent connections with the same hardware.
4. It’s Mature
Elixir is built on top of Erlang, a battle-tested 40-year-old language. Erlang runs highly concurrent applications like WhatsApp.
This title and quote from Wired is a great Erlang case study: Why WhatsApp Only Needs 50 Engineers for Its 900M Users
Additionally, Elixir has Phoenix, a world-class web framework for modern web apps modeled on Rails, which we all know and love.
Elixir has a large ecosystem of packages you can leverage while building your application. Not everything is available in an Elixir package, and for those cases, you can run any Erlang package natively from your Elixir application.
It’s also growing. It hasn’t caught up to Ruby, in terms of job posts on Hacker News, but as you can tell from this graph below, it is trending upwards while Ruby is trending downwards.
From my experience, since Ruby has been around for much longer and is easier to learn, there are a lot of great Ruby programmers and many who have a lot to learn. This makes it a little bit harder to hire Ruby engineers since you’ll have more candidates to filter through.
Let’s talk about the positives of Ruby. Essentially, why should someone choose Ruby?
Ruby is easier, and many developers already know it.
Ruby has been around longer (there's a Ruby gem for everything).
The sheer number of Ruby gems available is a lifesaver for developers. Any problem you’re facing has likely already been solved by someone else, available as a Ruby gem.
Easier to hire.
It's easier to hire a skilled Ruby developer, there's no question about that. There are a ton more in existence. We struggle to find skilled Elixir devs. What we find is motivated Ruby devs who want to learn Elixir, but then we have to train them.
Although Elixir is much smaller than Ruby, it's a growing community.
Can Elixir and Ruby work together?
Absolutely. You can run a small service with Elixir to support Ruby. Elixir compliments Ruby with speed. For example, you can do payment processing in Elixir but program it in Ruby.
You can also abstract critic/slow parts of your Ruby monolith into Elixir microservices with ease. The best route to take is to identify portions of the system around performance and scalability written in Ruby, then use Elixir instead.
What companies/apps use Ruby?
Ruby Vs. Elixir Head-To-Head
When deciding what program language to use, it comes down to this:
- If you’re building a simple app you need to get to market quickly, and you already know Ruby, go with Ruby.
- If you can invest the time to learn a new language and build something that will scale with you long-term, choose Elixir.
- If you're building something that needs to scale to handle a large volume of requests or process a lot of data, like a high-volume consumer app, choose Elixir.
Some companies using Elixir and a few selected case studies I liked.
Bleacher Report has gone from needing 150 servers to just five, thanks to its decision to move from Ruby on Rails monolith to Elixir Phoenix.
- ElixirConf Youtube Channel — All of the videos of speakers from ElixirConf starting back from 2017. Lots of great information and different perspectives.
- Elixir Forum — An active Elixir only forum where you can get quick and valuable feedback from engineers working in Elixir.
- Elixir tutorials and classes — A mixture of free and paid training classes.
- Elixir School — A destination for newbie and experienced Elixir programmers.
- Programming Elixir 1.6 — If you’re an experienced programmer looking for a comprehensive written resource on programming in Elixir, then this book is for you.
- Elixir training on Github
- Slack Bot tutorial — How to develop a Slack bot with Elixir and Phoenix.
- Learn Elixir in Y minutes — A high-level overview of Elixir on one page.
- How We Learned Elixir — A great story, with examples, about how engineers at a company learned Elixir.
Yes, I know this was a glowing review of Elixir. I believe Elixir was created specifically for programmer happiness. However, this doesn’t mean you should drop everything and rewrite all of your apps in Elixir. There is a time and place for everything.
Admittedly, Elixir is not for everyone. There's a significant learning curve, and it may be too much for some developers. If you're a casual Ruby developer, then Elixir also may not be for you. If you understand the benefits of a typed language and parallel computing can help you with your projects, then Elixir is for you.
If you're a tech leader and your infrastructure is already built in Ruby, there's no good reason to rewrite the whole app in Elixir. As mentioned earlier in this article, Elixir can fill in the gaps of existing Ruby applications.
You'll want to look at your stack and identify portions of the system that are having issues around scaling or reliability. You could rewrite just those services in Elixir. Or you may want to pick a new piece of functionality and write an Elixir microservice.
It's simpler to supplement your existing Ruby application with Elixir over another similar language, such as Go. Why? It's easier for your Ruby engineers to learn Elixir (and they won't lose their hair trying to debug concurrent nonsense).
In the end, Ruby is still a great language. We just feel Elixir is a better language. It’d be a good idea to consider Elixir on your next project. I hope this guide helps with your decision.
Have any questions? Feel free to reach out.