Announcing PushEx: Open-Source WebSocket Push Server in Elixir

I’m happy to announce the open-sourcing of a project that I’ve been putting a good deal of time and effort into, PushEx. PushEx is a WebSocket push server built in Elixir; it allows you to send payloads from your servers to your users in real-time. In this post, I will go in-depth about the problem PushEx solves, why I’m excited about it, and why Elixir is perfect for the problem space.

The Problem

As consumers of an online web application use the application, asynchronous processes may take place that the user needs alerted to. Some examples of this include:

Notifying a user when they get a new message

Alerting the user when their multi-minute import finishes

Updating the frontend website as backend data models are updated

WebSockets allow an elegant solution to this problem because they enable the backend servers to maintain a direct connection to the user. The servers can then send data to the connected users nearly instantly.

However, WebSockets bring about their own problems. The web server must be capable of handling all of the connections and keeping them alive every so often. In a production deployment, multiple servers must also be able to have knowledge about each other, because the user may be connected to server A but the request for a push goes through server B. Phoenix and Elixir, the foundation that PushEx leverages, provide excellent solutions to these problems.

Elixir, A Great Solution

Elixir is an excellent language for solving the problem of WebSockets. Some properties of Elixir that are great for this problem are:

Parallel processing power for efficient handling of many connections

Built-in networking between multiple servers in a deployment

Ability to hold very large sets of processes (supports many connections)

Incremental garbage collection per process (many connections won’t freeze at the same time)

Error separation between processes (connections won’t crash each other)

Phoenix leverages the power of Elixir to provide an excellent WebSocket solution, and PushEx provides these same benefits because it is built using Phoenix Channels. In fact, Phoenix has been benchmarked at being able to support over 2 million connections on a single large box. While this is a fun benchmark, real world implementations will often have many servers networked together for efficiency, scalability, and redundancy. Phoenix provides a solution to the problems that come with distributed servers through “Presence”, a mathematically efficient solution to knowing the state of the distributed WebSockets.

Challenging to Bring to Production

Despite the effectiveness of Elixir and Phoenix for WebSockets, developing a production-ready push server is not a trivial task. Throughout the development of PushEx, an improvement was found/developed to improve Phoenix’s JS client availability and the properties of many simultaneous connections were examined. This work helps make PushEx production-ready and scalable to a large number of clients.

While there are large companies using WebSockets in production successfully, it is easy to see that small details can be missed. The goal with PushEx is to identify, solve, document, and educate on these small details.

PushEx seeks to make developing your production-ready push server easy! The Getting Started - Standalone Installation guide allows you to get up and running in less than 10 steps, with only a bit of application-specific code needing developed.

Using PushEx

PushEx has been designed to be easy to setup and will be comfortable for Elixir developers. There are, however, quite a few guides written that will help make the process of developing and deploying PushEx easier. You can find these guides on hexdocs.pm.

PushEx is currently in a 1.0.0 release candidate. An implementation has been developed for use in production at SalesLoft, and will be tested there within 30 days. Once it is in production, the 1.0.0 release will be shipped. I do not anticipate much changing between now and then, as the core system is similar to what is already in use on another internal project.

Giving Back to Elixir Community

Elixir and Phoenix are providing the solid backbone of PushEx and help to make it great. To that end, I want to invite the community to ask any questions they have on the PushEx project so that they may have some of their challenges solved. Please feel free to ask any question on the PushEx Issue Tracker regarding any code or ideas in the project. I will personally read and answer each one to help provide back to the community.

Explore PushEx on: