GenServer.call is not just for returning a response

I have been working on a side project using Elixir with a friend who is new to the language. He has some functional programming experience, but none using the Erlang/Elixir actor model. It was tricky at times to explain the fact that a single actor in this world can do only one thing at a given time even though you often hear about the BEAM VM and its abilities to handle concurrency. The reality is that multiple actors are often needed to get things done.

Somewhat related to this are the concepts of cast and call in a GenServer. At first glance when building a system with OTP fundamentals it is easy to think the following:

It says in the docs that cast is asynchronous. Since I do not need a reply in this situation, the cast will be better than a call. Asynchronous code seems cool. Synchronous code doesn’t seem cool. I want to be cool.

Unfortunately, the idea that a cast is superior or gives you an advantage can potentially become a nasty problem as you scale out. I’ve found it much safer to always start with a call which allows me to process heavy workloads at a much more consistent rate without worrying about overloading portions of my systems. Having said that, a cast is perfectly fine to use in the right scenario. However, if your workload is capable of fluctuating heavily and can spike at times, it may be best to keep things under control using a call or some other form of backpressure to keep clients from overloading portions of your system.

The official learning guide on the elixir-lang website has a small section on the same topic which can be found here. Regarding the usage of a call that documentation says: