Skip to content
Development
Skill

/oban

Use when writing, scheduling, testing or debugging Oban jobs, even for a how-to question: workers, cron, retries, unique jobs, queues, Pro Workflow/Batch. Load it before touching job code; it holds the job rules.

From plugin
claude-elixir-phoenix
574106 skills37 agents2 commands

Claude Code

$ npx -y skills add oliver-kriska/claude-elixir-phoenix --skill oban --agent claude-code

SKILL.md

oban.SKILL.md
name: oban
description: "Use when writing, scheduling, testing or debugging Oban jobs, even for a how-to question: workers, cron, retries, unique jobs, queues, Pro Workflow/Batch. Load it before touching job code; it holds the job rules."
effort: medium
user-invocable: false
paths:
  - "**/workers/**/*.ex"
  - "**/*_worker.ex"
  - "**/*_worker_test.exs"
  - "**/*_job.ex"

Oban Background Jobs Reference

Quick reference for Elixir Oban patterns.

Oban Pro Detection

**Before applying patterns, check for Oban Pro:**

grep -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 `${CLAUDE_SKILL_DIR}/references/oban-pro-basics.md` for all patterns and migration guide.

---

Iron Laws — Never Violate These

1. **JOBS MUST BE IDEMPOTENT** — Safe to retry. Use idempotency keys for payments 2. **JOBS MUST STORE IDs, NOT STRUCTS** — JSON serialization. `%{user_id: 1}` not `%{user: %User{}}` 3. **JOBS MUST HANDLE ALL RETURN VALUES** — `:ok`, `{:error, _}`, `{:cancel, _}`, `{:snooze, _}` 4. **ARGS USE STRING KEYS** — Pattern match `%{"user_id" => id}` not `%{user_id: id}` 5. **UNIQUE CONSTRAINTS FOR USER ACTIONS** — Prevent double-click duplicates 6. **NEVER STORE LARGE DATA IN ARGS** — Store references (IDs, paths), not content 7. **SMART ENGINE: NEVER USE `attempt` TO LIMIT SNOOZES** — Snooze rolls back attempt counter. Use `meta["snoozed"]` instead. Causes infinite loops

Quick Worker Template

defmodule 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 Value Meanings

| 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 |

Quick Decisions

Which Queue?

  • **Critical operations** → High concurrency (20+)
  • **Mailers/Webhooks (I/O)** → Medium concurrency (30-50)
  • **CPU-intensive** → Low concurrency (3-5)
  • **External APIs** → Use `dispatch_cooldown` for rate limiting

Testing Pattern

use 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})

Common Anti-patterns

| 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 |

References

For detailed patterns, see:

  • `${CLAUDE_SKILL_DIR}/references/worker-patterns.md` - Worker options, backoff, timeout
  • `${CLAUDE_SKILL_DIR}/references/queue-config.md` - Queue design, pool sizing, cron, Smart Engine
  • `${CLAUDE_SKILL_DIR}/references/testing-patterns.md` - Testing, assertions, drain (OSS + Pro)
  • `${CLAUDE_SKILL_DIR}/references/oban-pro-basics.md` - Pro.Worker, Workflow, Batch, Chunk, Relay, plugins
Read more
@oliver-kriska
Ships withclaude-elixir-phoenix

Docs: phxagents.dev -- install guides per runtime, the runtime compatibility matrix, all 26 Iron Laws, and a browsable skill and agent catalog. Claude Code is great.

574106 skills37 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
574
Star history of oliver-kriska/claude-elixir-phoenix on GitHub, a chart by star-history.com

Other skills on claude-elixir-phoenix.

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about oban.

Which coding agents can use oban?
oban installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.