Elixir and Phoenix are promising to become a productive foundation for creating backend applications.
While the software ecosystem is not yet on par with Rails, we think that this technology is on a very good trajectory. It is already superior in a number of use cases, and we are always excited to build products with them when they are a good fit.
Ruby and Rails have served us very well over the past years. The combo is our go-to solution for building applications on the server backend for projects of any size. Ruby is fun to write, and Rails has a lot to offer with its huge ecosystem of solutions that simply plug into the framework.
But the architecture has its quirks and often leads to poorly maintained codebases. This relates to Rails being an opinionated framework offering only a small set of concepts that developers often try to fit every problem onto. Breaking out of these concepts is a big mental leap, and a huge part of the ecosystem of ready-made solutions does not support usage outside the framework’s patterns.
Ruby provides many concepts from several language paradigms and blends them nicely. But it is particularly weak on parallelism and won’t be able to improve significantly soon. There isn’t much of a safety net either, by extreme tolerance towards the programmer and the absence of a typesystem euphemistically coined “duck typing”. Also, its take on object orientation - while requiring less ceremony compared to many other languages - still seemed complex to me after years!
Around two years ago, I took some time to research what other languages and frameworks had to offer. I found a couple of interesting ones, but none of them really stuck with me. Things looked either too simplistic or too complicated for the everyday job, or they solved a problem that we didn’t face.
When I discovered Elixir, I immediately knew I hit upon something special, something very different from all the others. To me, Elixir looked like a box of building bricks to construct systems with. And that is very true! What I had discovered was Elixir’s immediate inheritance from Erlang, the language and platform Ericsson built in the 80s for their telephony switches.
But to build a large web application backend we also need higher-level abstractions, a web application framework. Phoenix is to Elixir what Rails is to Ruby and it also looks deceptively similar to Rails.
What Elixir and Phoenix have to offer
Similarly to Ruby, writing and organizing code is low-ceremony in Elixir, allowing to incrementally build things up and easily check the results at each step. For me, the unique selling point of Elixir is that this is still the case AND that we can build things that would be hard if not impossible in other languages. Elixir inherits two characteristics from the platform it is built upon, namely Erlang:
- the ability to maintain long-running independent connections and process communication with very little overhead
- failure isolation and recovery
Think of chat, think of gaming or in other words: think of many thousands of mobile devices keeping a connection to your service. Think of bots, keeping a conversation state. All these are use cases where those two points have a tremendous impact on stability and scalability.
My bet is that the platform design principles that make these qualities of the running software possible will also improve the software at rest. They will naturally drive developers towards separation of concerns, and the amount of state being kept around at any point in the code will be small.
Elixir is a functional language with immutable data. Purely functional code is certainly simpler to test and many people expect to see fewer bad surprises because the path of data is easier to follow. Data modification becomes data transformation and thus much more explicit, albeit a bit more cumbersome. This might be a tough sell for people doing object oriented programming for years.
What Elixir and Phoenix don’t offer (yet)
The community around Elixir and Phoenix is still small, much smaller than the Rails community, which is itself small when compared to e.g. Java. This results in fewer tools, less documentation or support, fewer questions on StackOverflow and so on. The community certainly has a bus factor and taking a wrong turn can still have a massive negative impact.
I have attended a couple of community events close by as well as abroad. I really like that the community feels technically more competent and deep, is calm and considerate. What is often ignored is the fact that behind the Elixir community, there still is the Erlang community as well. Most of the software can be shared between the two adjacent ecosystems, let alone architecture patterns and experiences. I have the impression that a larger community is forming around the runtime (similar to what happened with the JVM). The platform is even expanding off the server backend into IoT devices. So, in a way the community is larger than it may seem.
About performance and scalability
Yes, Elixir is more performant than Ruby. The reasons I’m writing this so far down at the bottom of this post are:
- I don’t have solid data to back this claim, and benchmarks can’t be trusted
- Performance is certainly nice to have, but not really all that important (with exceptions)
I can say this about Elixir’s performance: Elixir runs as compiled bytecode on the Erlang virtual machine; Web requests in Phoenix, when not touching a database or external service, usually finish within less than a millisecond. Go figure and compare for yourself. Also, note that latency and throughput are both performance characteristics, and the Erlang VM is optimized not for throughput, but for latency.
Don’t crunch numbers in Elixir. It’s slow.
The way we have scaled Rails applications in the past, by scaling out independent workers behind a load balancer, certainly works for Phoenix as well. But there are other ways of handling the necessary load that go far beyond this. You may never need them, but they exist nonetheless and they are interesting.
The Erlang VM is a distributed virtual machine by nature, so multiple nodes can connect to form a cluster and exchange work and data. All this works semi-transparently, because the concepts for this are natural extensions of the platform concepts that beginners learn. All data types, including functions, are serializable transparently. Not only can you build your own fault-tolerant eventually-consistent cluster, but now it can even operate its business logic on every node! (Don’t roll your own, there’s a framework for this)
Making the shift
The Elixir language itself is relatively simple and easy to learn. Making the mental shift to the new paradigms is the hard part. It’s really hard if you have been programming imperatively, with inheritance, with mutation, for years. So in the beginning, it’s really tricky to tell if the new material is complex or just difficult.
We currently use Elixir for projects where technical demands make it a good fit. We are not making a complete shift away from Rails any time soon—this will be a gradual process tuned to what both ecosystems have to offer, and it may also never complete. But we are excited to have another tool at our disposal to solve different problems.
If you like what you’re reading and want to play with cutting edge technologies like ES6 or Elixir feel free to apply at 9elements.
Image by Dariusz Sankowski