Periodic tasks with Elixir
No more Googling for Cron syntax
I’d argue that most projects I’ve worked on over the years all have eventually included a periodic task of some sorts; daily reminder email, overnight processing task, polling an API that doesn’t provide a web hook etc.
With Ruby the answer was always a cron job that would invoke a rake task. This had couple of problems with it, first I could never remember the crontab format. Second was where to place the configuration and how to make sure it was up to date.
Gems like Whenever would help fix many of my grievances but with Elixir there’s in my opinion something even nicer.
Using receive/1 for timeouts
Elixir has a function
receive/1 which is defined in the Kernel.SpecialForms module and is available for use anywhere in your code without the module prefix.
receive/1 takes an optional
after clause with a timeout value that gets executed if the process has not received a matching message in the given time. We can combine this with a recursive call to execute code at given intervals.
If that sounds cryptic I hope this helps
defmodule Example dodef process() do
IO.puts "5 seconds elapsed"
If you were to call the
process/0 function here it would keep printing “5 seconds elapsed” every 5 seconds.
Creating a periodic Task module
The function above isn’t terribly useful by itself, for one it never returns and besides we’d want it to start when the application starts.
We can create a module that starts our process in a Task and can be added to the applications supervision tree
defmodule Example.BitcoinPriceUpdater do
use Task def start_link(_arg) do
end def poll() do
end defp get_price() do
# Call API & Persist
IO.puts "To the moon!"
If you are on Elixir 1.5 or newer by using the
use Task at the top of your module your Application supervisor can do something like this
defmodule Example.Application do
@moduledoc false use Application def start(_type, _args) do
children = [
] opts = [strategy: :one_for_one, name: Example.Supervisor]
If you are on an older version of Elixir you’ll have to specify the children with something like this instead
children = [
In any case what you have is a module as part of your Application supervision tree that is started automatically when your Application is started and it will keep calling the given piece of code periodically.
There you have it a simple little module that you can use to add periodic tasks to your applications with ease and no more worrying about updating the crontab.
In my experience the timeout is accurate enough for most tasks like this and I’ve had couple running in production for a year or so now and it’s not given me any trouble.
Having said that I wouldn’t rely on this for anything where accuracy is very important and also keep in mind that if your process crashes or you restart the app the timer starts from 0.
Please do click the 👏 icon below if you liked this post and follow me here or on Twitter @efexen to hear about new articles. If you haven’t already can I recommend checking out my Elixir Refactoring Series as well 👍