Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Oban job processing — workers, perform/1 (OSS) and process/1 (Pro), queues, cron, retries, unique jobs, idempotency, Oban Pro (Workflow, Batch, Chunk, Smart Engine), Testing. Use when writing Oban workers, queue config, or debugging jobs.
.claude/skills/oliver-kriska-oban/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | -8% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 17% | 0% |
| case-15 | ✗→✓ | ▲ Improved | 0% | 0% |
| case-11 | ✓→✗ | ▼ Worse | 58% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 120% | 0% |
Quick reference for Elixir Oban patterns.
Before applying patterns, check for Oban Pro:
bashgrep -E "oban_pro|oban_web" mix.exs grep -r "use Oban.Pro.Worker" lib/ grep -r "Oban.Pro.Engines.Smart" config/
If Oban Pro detected, use Pro patterns for ALL new workers:
| Standard Oban | Oban Pro | |---------------|----------| | use Oban.Worker | use Oban.Pro.Worker | | def perform(%Job{}) | def process(%Job{}) | | Oban.Testing | Oban.Pro.Testing | | Advisory lock engine | Oban.Pro.Engines.Smart |
Pro features (all optional): args_schema (typed args), Workflows, Batches, Chunks, Relay, hooks, encryption, deadlines, chaining, Smart Engine (global concurrency + rate limiting). Pro plugins (DynamicCron, DynamicLifeline, DynamicPruner) enhance OSS equivalents — swap module, don't run both. See references/oban-pro-basics.md for all patterns and migration guide.
%{user_id: 1} not %{user: %User{}}:ok, {:error, _}, {:cancel, _}, {:snooze, _}%{"user_id" => id} not %{user_id: id}attempt TO LIMIT SNOOZES — Snooze rolls back attempt counter. Use meta["snoozed"] instead. Causes infinite loopselixirdefmodule MyApp.Workers.ExampleWorker do use Oban.Worker, queue: :default, max_attempts: 5, unique: [period: {5, :minutes}, keys: [:entity_id]] @impl Oban.Worker def perform(%Oban.Job{args: %{"entity_id" => id}}) do case process(id) do {:ok, _} -> :ok {:error, :not_found} -> {:cancel, "Entity not found"} {:error, :rate_limited} -> {:snooze, {5, :minutes}} {:error, reason} -> {:error, reason} end end end
| Return | State | Behavior | |--------|-------|----------| | :ok | completed | Success | | {:ok, value} | completed | Success with value | | {:error, reason} | retryable | Retry with backoff | | {:cancel, reason} | cancelled | Stop permanently | | {:snooze, seconds} | scheduled | Delay and retry |
dispatch_cooldown for rate limitingelixiruse Oban.Testing, repo: MyApp.Repo # Assert enqueued assert_enqueued worker: MyApp.Worker, args: %{id: 1} # Execute and verify assert :ok = perform_job(MyApp.Worker, %{id: 1})
| Wrong | Right | |-------|-------| | %{user_id: id} pattern match | %{"user_id" => id} (string keys) | | %{user: %User{}} in args | %{user_id: 1} (IDs only) | | No idempotency for payments | Use idempotency keys | | Ignoring return values | Handle all outcomes explicitly |
For detailed patterns, see:
references/worker-patterns.md - Worker options, backoff, timeoutreferences/queue-config.md - Queue design, pool sizing, cron, Smart Enginereferences/testing-patterns.md - Testing, assertions, drain (OSS + Pro)references/oban-pro-basics.md - Pro.Worker, Workflow, Batch, Chunk, Relay, pluginsOther measured skills in the registry, with their headline benchmark lift.