Scrapping a Server for Serverless

My personal project for the last few weeks has been Pointer, a (now serverless) planning/pointing poker web application. I hacked together the first prototype over a weekend, and it was unstable to say the least. It could handle about three good connections before it started losing connections and/or having memory issues.

The first protoype was made of two separate repositories: one for the front-end which was a very basic Vue client and one for the server which is where most of the work was being done on a Node.js Express server. This first iteration used socket.io and a bunch of disparate endpoints the client would call when they voted. It worked pretty well when there were only two or three clients in on session. More users than that, or if somebody left and rejoined a session, would cause everything to start falling apart. I didn't expect many users, but the goal was to build something my team at work could use and we have more than three users so something needed to be improved.

I tried using websockets a little bit, but managing which connections were in which rooms made the code a mess. Worst of all, it didn't seem to improve the reliability which was the whole point.

I wasn't sure where to go with the project when one of my coworkers (thanks Austin) recommended checking out Pusher. Switching over to use Pusher pretty much saved the project. Over the next few iterations I moved more and more of the real-time interactions over to client events so that all the communication was taking place over Pusher instead of my self-hosted server.

Eventually I managed to slim down the server to only have one endpoint used to connect users to a presence channel. This final piece useds a secret key so there was no way I was going to be able to move it over to the frontend.

At this point I was running a simple server that only got hit when a user was first joining a session. After that, all communication happened on the front-end which was being served from Netlify as a static site. At this point I just hosted the backend code on a cheap VPS I was using for other test sites. I was pretty happy with this version of the site and left it alone for a little while.

Over the next few weeks I took down the other test sites I was using that were also hosted on the VPS, until finally it was just hosting Pointer. I didn't feel like spending a few bucks a month just to keep this service running, but I also didn't want to shut it down. Once again I started looking for some options on how I could host the authentication code somewhere for free without compromising my secret key or crippling performance.

I checked out AWS Lambda but wasn't excited about learning how to configure and manage an entire AWS account for this small project. That's when I stumbled across Netlify Functions which is basically a simplified way to host AWS Lambda functions. As I was already hosting the front-end on Netlify, this seemed like the perfect solution. They have a much lower free tier than AWS itself, but seeing as how Pointer currently averages about 0 users per month I figured it's more than enough.

Functions currently supports only JavaScript and Go, but because I had written the server with Node it was easy to move over. I stripped out all the Express code, copied what was left into a function file I created in the frontend repository, and then fixed up some differences in how environement variables were loaded and how the response needed to be returned.

The entire project now lives in a single repository so it's easier to figure out how the site works. Deploys are extremely simple with everything just going to one place. Best of all, it's entirely free for me to host.

Moving forward I hope to start adding more features and UX touches, but I'm very happy with where it's at right now. If you or your team are looking for a simple and responsive pointing poker tool, check out Pointer at pointer.nathanheffley.com.