> One of the strengths of GenServers is that they allow us to spin one up per user very easily, so they don't become a bottleneck where the Agent does.<p>Agent is a special case of GenServer[1]. With the same luck we could spin up an agent per user.<p>[1] [Agent.start_link/2](<a href="https://github.com/elixir-lang/elixir/blob/9137fd1cb2368bb1bc3a9c590440dffc9f5fed62/lib/elixir/lib/agent.ex#L271" rel="nofollow">https://github.com/elixir-lang/elixir/blob/9137fd1cb2368bb1b...</a>)
In addition to what the offer recommended in the "Scheduling work" section, using the `:timer.send_interval()` can be useful if you want to do something every X seconds, instead of every X + Y seconds, where Y is the time it takes to process the "work" message.<p>Also I prefer to use `handle_continue` instead of `schedule_work()` style (which in a lot of cases pre-date the introduction of `handle_continue`).
Having reliable scheduling in the language itself seems like it would simplify a ton of software that's currently reliant on a lot of message queueing and cron duct tape. Running BEAM in production still scares me, but that's one reason to conquer the fear.
Regarding caching, after years of not using any, we finally ended up using nebulex (with the in-memory cache) and it’s been excellent.<p>The ability to add cache annotations to functions feels really clean.<p>There’s also the ability to have cluster wide state but we haven’t set that up yet. We will soon.