Background

For the past semester, I have deployed a custom shortlinker service and my personal website on a Google Cloud Compute Free Instance. The custom shortlinker is a rewrite of the CS61A Shortlinker in Elixir, which was a good way for me to learn the new language. Upon deploying the Elixir version, however, I noticed that CPU usage hovered around a constant 100%, even the system was idling. I left it alone for a while, noting that it was responding to requests fairly quickly, leaving me to think that it was likely the BEAM that was idling.

More Research

Recently, I got back into Elixir, and curiosity (+ paying bills) prompted me to investigate into the issue more. I came across this blog, which answered all of my problems.

… enabling busy waiting causes the CPU to be saturated above 95%. Disabling busy waiting causes CPU utilization to scale with the workload.

That’s insane! Could it be possible that the BEAM was running empty cycles to claim the CPU, hence stealing cycles from other processes? There was only one way to tell.

My Own Change

I decided to make the changes the blog specified by adding these following lines to the BEAM arguments:

+sbwt none
+sbwtdcpu none
+sbwtdio none

In the blog, they used Distillery, but I use default Mix releases, so I will document the changes below:

  1. Documentation:
  2. Add the required VM configuration files: mix release.init.
  3. Modify the VM configuration file by adding
     +sbwt none
     +sbwtdcpu none
     +sbwtdio none
    

    to rel/vm.args.eex.

  4. Recompile and deploy!

And with that, I noticed that there was a dramatic reduction in compute:

Beam Reduced Usage

Note that CPU usage is nearly zero, where as before it was ~100%! This frees up the CPU cycles for redeployments to this server and for more concurrent apps running (Build times are cut by more than a half!). I will be monitoring this new deployment for any regressions, but it appears to be a very solid improvement.