Recipe

Oban (Elixir) primer

Oban is a robust, Postgres-backed job processing library for Elixir. It gives you durable background jobs with cron scheduling, retries, unique constraints, and observable telemetry, all without an extra broker. This primer walks through wiring Oban into a Phoenix app and shipping your first worker.

1.Install and configure

Add Oban to your dependencies, run the migration generator, and point it at your existing Ecto repo. No Redis, no RabbitMQ, no separate infrastructure to babysit.

# mix.exs
defp deps do
  [{:oban, "~> 2.17"}]
end

# config/config.exs
config :my_app, Oban,
  repo: MyApp.Repo,
  plugins: [Oban.Plugins.Pruner],
  queues: [default: 10, mailers: 20]

# application.ex
children = [MyApp.Repo, {Oban, Application.fetch_env!(:my_app, Oban)}]

2.Define a worker

Workers are plain Elixir modules implementing the Oban.Worker behaviour. The perform/1 callback receives a struct with your args. Return :ok, an error tuple, or :discard to control retry semantics.

defmodule MyApp.Workers.SendWelcomeEmail do
  use Oban.Worker, queue: :mailers, max_attempts: 5

  @impl Oban.Worker
  def perform(%Oban.Job{args: %{"user_id" => user_id}}) do
    user_id |> MyApp.Accounts.get_user!() |> MyApp.Mailer.welcome()
    :ok
  end
end

# enqueue
%{user_id: 42}
|> MyApp.Workers.SendWelcomeEmail.new()
|> Oban.insert()

3.Schedule, dedupe, and observe

Cron entries replace your old crontab. Unique constraints prevent duplicate jobs within a window. Telemetry events feed into Oban Web for a live dashboard of queues, retries, and failures, so you can stop guessing what your workers are doing in production.