By Geoffrey Lessel
This article, excerpted from Phoenix in Action, introduces you to the power of web development using Elixir and the Phoenix framework.
Arguably the biggest impact on the open-source web in the 2000’s was the release and adoption of Ruby on Rails—a web framework written on the Ruby programming language. This allowed developers to quickly and easily get a dynamic web site up and running in little time. The famous example from that time was creating a blogging engine in fifteen minutes. It allowed developers great productivity and “Web 2.0” exploded.
After Ruby on Rails, many new web frameworks attempted to match or outdo Ruby on Rails in terms of features and developer happiness, and a go-to web framework for each major programming language emerged. In that vein Phoenix was born.
What is Phoenix?
Phoenix is a web framework that attempts (and, in my opinion, succeeds) to help make the creation and maintenance of dynamic websites much simpler. Phoenix doesn’t attempt to copy the big player in this space: Ruby on Rails. Phoenix is built on top of the Elixir programming language (which is a functional language), and Ruby is an Object Oriented programming language. Although Phoenix has best practices for structuring and maintaining your application, it’s not as dogmatic as Ruby on Rails and other frameworks are — giving you flexibility to write your application how you see fit. Phoenix goes beyond many web frameworks, as well. For example, Phoenix has the concept of Channels built-in. Channels allow for “soft-realtime” features to be easily added to applications. This is what allows you to have chat applications, instant push updates to thousands of simultaneous users, and page updates for the user without a full-page refresh. Although these kinds of features are difficult to add in other languages and frameworks, it borders on trivial for Phoenix applications. Whole books can be written about how to get these features into web applications using other web frameworks (or rolling your own).
Elixir and Phoenix Versus the Alternatives
This article isn’t intended to be a bullet-point list of things that Phoenix and Elixir do well over other alternatives, but to introduce you to the power of Phoenix and Elixir.
What can you do with real-time communication? Well, any time you want to push information to many users simultaneously, you’ll need a solution for that. That could be with a chat application where users can send and receive chat messages to thousands of other users and you need to keep each client up-to-date when another client’s user submits a new message. It could be something more complex, like an auction site that wants to provide users visiting the auction item’s page up-to-the second information regarding the state of the bids. Maybe it’s a workplace collaboration site where users are sharing files and even working on the same file simultaneously. Or perhaps there’s a real-time multiplayer game server that you want to build and you need to ensure that all players have the same information at the same time. Many different situations require real-time channels, and there are many more in which it’d be beneficial. Figure 1 illustrates a simple situation in which bandwidth can be saved and the user experience improved with pushing data to the user instead of requiring the user to pull the data from the server.
Figure 2. Traditional “pull” refreshed require the user to initiate the request and the server to return the entire web page again.
Figure 3. A “Push” requests originates from the server and “pushes” new information to the user which is typically only that which changed, greatly reducing payload and speeding up page rendering.
Elixir can spawn and efficiently handle hundreds of thousands of processes without blinking an eye (we go into a bit more detail in the section about Elixir below). You’ve also read briefly about Phoenix’s concept of channels which allow real-time communication. Phoenix spawns each channel into its own process to prevent one process from damaging or taking down any of the others — they’re beautifully isolated.
Using these processes and channels, Phoenix can handle a couple hundred thousand connections on a single server! Granted, kudos to you if your web application ever has hundreds of thousands of simultaneous users wanting to communicate in real time—but that gives you an idea of the power of Phoenix and Channels running within processes.
Sometimes working in development you’ll want to do a long-running computation or process but won’t want to keep the user from interacting with your software, whether it’s on the web or locally with some user interface. For example, a user of a digital product e-commerce site may want to purchase a product which is customized and then can be downloaded. Once the user finalizes the purchase, you don’t want to require the user to wait on that page until the personalization process is complete. Instead, you’d like for them to continue to browse your store or set up their profile. This is a simple scenario in where background computation can play a role.
Figure 4. Background processes can help do complex work without holding up the main responses to the user.
If your application needs to do any more than a small amount of computation in the background (normally asynchronously), then it’s a perfect fit for something built on top of Elixir like Phoenix. It’s trivially easy to kick off background, asynchronous processes with Elixir.
This fits in perfectly with the real-time communication features of Phoenix. Once the long-running process is complete, the server could send a message through the Channel to the user’s client that the process is complete and either display the results directly on the client or provide a link or further instructions to retrieve the results at a later time.
Low Hardware Requirements / Low-cost Scaling
If you look at any hosting provider’s offerings, you’ll notice that most of the time, adding more CPU power/cores costs less than adding more RAM. This fits perfectly with the way Elixir works. Elixir automatically uses all the different CPU cores available to it and takes up a relatively small amount of RAM in order to run. Compare this to a web framework and language like Ruby on Rails which is RAM hungry.
Other web frameworks built on differing programming languages CAN scale, but if you’re looking for a low-cost way to scale quickly, then Elixir and Phoenix would be a good choice. Pinterest explains in a blog post [1: https://medium.com/@Pinterest_Engineering/introducing-new-open-sourcetools-for-the-elixir-community-2f7bb0bb7d8c] that they moved one of their systems from Java to Elixir.
“So, we like Elixir and have seen some pretty big wins with it. The system that manages rate limits for both the Pinterest API and Ads API is built in Elixir. Its 50 percent response time is around 500 microseconds with a 90 percent response time of 800 microseconds. Yes, microseconds.
We’ve also seen an improvement in code clarity. We’re converting our notifications system from Java to Elixir. The Java version used an Actor system and weighed in at around 10,000 lines of code. The new Elixir system has shrunk this to around 1000 lines. The Elixir based system is also faster and more consistent than the Java one and runs on half the number of servers.”
It’s Not All Roses
Although the Elixir language and the Phoenix framework are awesome and are usually what I reach for when starting new projects, it isn’t always the de facto best choice for the job. In some areas Elixir doesn’t do as good a job as an alternative would.
Time to Productivity: If you’re already productive in a different web framework using a different programming language, it may be hard to justify the cost of getting up to speed in something new like Elixir. If you’re getting started in development, one consideration is how long it takes you to become productive in your new chosen language. Some people I’ve spoken to believe it’s harder to learn functional programming than Object-oriented programming, while others swear it’s the other way around. Regardless, I believe that Elixir and Phoenix offer enough reasons for you to take the plunge and learn the language regardless of your past experience levels.
Numbers: Elixir isn’t a number-crunching powerhouse. It’ll never match the pure computational speed of something lower-level like C or C++. I’d even go as far to say that if you’re looking to primarily crunch large numbers, even Python is a better choice. Elixir can do it and do it well, but it won’t win in a head-to-head competition in this area.
Community: Although the community behind Elixir, Phoenix, and Erlang is helpful and enthusiastic, it’s not as large as a community for something like Ruby, Python, Java, or even PHP. Those languages have a deeper and longer history in the web application world and it might be easier to find help with your project in one of those worlds. More and more meetups, conferences, blogs, jobs, etc. are arriving all the time for Elixir and I believe the future holds great things for the Elixir community.
Packages: Going along with the above comment regarding the size and age of the community surrounding Elixir versus other languages, the number of open-source packages available to use in your project is smaller. As of the time of this writing, there are currently less than 4,500 packages available on hex.pm, the package manager source for Elixir. Contrast that to rubygems which has over 8,500 packages and PyPI (the Python Package Index) which has over 109,000. Although it may be harder to find something that does exactly what you used in previously programming languages, more packages are being built all the time. It also means there’s space for YOU to create a new helpful package and help grow the community.
Deploying: Deploying an Elixir application is (including ones that use the Phoenix web framework) pretty tricky and involves multiple steps. Beyond that, those steps still aren’t quite clearly defined nor have mature tools to help in the process.
Phoenix provides a lot of things that help you add normally-complex features to your web applications but it won’t be the foundation of your application: Elixir will. Although it may be strange to read that in a book specifically about Phoenix, the truth is that Phoenix derives its powers from the amazing Elixir programming language.
Hungry for more? Go read the first chapter of Phoenix in Action here, for free!