# Background Jobs

> Use when designing asynchronous job processing. Covers queue selection, idempotency, retry and backoff policy, scheduling, poison messages, and observability for work that happens outside the request.

- **Type:** Skill
- **Install:** `agentstack add skill-nimadorostkar-claude-skills-collection-background-jobs`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [nimadorostkar](https://agentstack.voostack.com/s/nimadorostkar)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [nimadorostkar](https://github.com/nimadorostkar)
- **Source:** https://github.com/nimadorostkar/Claude-Skills-collection/tree/main/skills/backend/background-jobs
- **Website:** https://github.com/nimadorostkar/Claude-Skills-collection

## Install

```sh
agentstack add skill-nimadorostkar-claude-skills-collection-background-jobs
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Background Jobs

## Purpose

Move work out of the request path without losing it. A job system is a distributed system with a friendly interface; the failure modes are the same, and they are hidden until they are not.

## When to Use

- Work that is slow, retriable, or must survive a request timeout: emails, exports, webhooks, media processing.
- Scheduled and recurring work.
- Diagnosing duplicate side effects, stuck queues, or jobs that silently disappear.

## Capabilities

- Queue and worker design, including priority and isolation.
- Idempotency and exactly-once effects.
- Retry policy: backoff, jitter, attempt limits, dead-letter handling.
- Scheduling: cron jobs, delayed jobs, and deduplicating them across instances.
- Observability: queue depth, age, failure rate.

## Inputs

- The work to be done and whether it can safely run twice.
- Latency expectations: seconds, minutes, or overnight.
- Volume, and how bursty it is.

## Outputs

- Job handlers that are idempotent by construction.
- Explicit retry and DLQ policies per job type.
- Alerts on queue depth and oldest-message age.

## Workflow

1. **Make it idempotent first** — Before anything else. A job will run twice; design so that this is harmless. Key the side effect, not the invocation.
2. **Pass identifiers, not objects** — Enqueue `{"order_id": "..."}`, not a serialized order. By the time the job runs, the object may be stale.
3. **Set the retry policy per job** — A transient network failure deserves exponential backoff and ten attempts. A validation failure deserves zero retries and a DLQ.
4. **Isolate the queues** — A flood of low-priority image resizes must not delay password-reset emails. Separate queues, separate workers.
5. **Deduplicate scheduled work** — With multiple instances, every instance's scheduler fires. Use a lock keyed on the job name and window.
6. **Alert on age, not just depth** — A queue with 10 messages that are 3 hours old is a worse signal than a queue with 10,000 that are 5 seconds old.

## Best Practices

- Every job handler must tolerate being called twice with the same arguments. This is the single rule that prevents most job-system incidents.
- Never enqueue inside a database transaction that has not committed. The worker will pick the job up and find no row. Use the outbox pattern or an after-commit hook.
- A job with no timeout will eventually hang and hold a worker forever. Set one.
- Retry only what is retriable. Retrying a 400 from an upstream API twenty times is a way to get rate-limited for a permanent failure.
- Log the job ID, the attempt number, and the argument identifiers on every execution. Without this, debugging is guesswork.
- Keep handlers small. A job that does five things fails partway through the third.

## Examples

**Idempotent handler with a natural key:**

```python
@job(queue="billing", max_attempts=5, backoff="exponential", timeout=30)
def send_invoice(invoice_id: str) -> None:
    invoice = Invoice.get(invoice_id)

    # The natural idempotency key: an invoice is sent at most once.
    if invoice.sent_at is not None:
        logger.info("invoice_already_sent", extra={"invoice_id": invoice_id})
        return

    message_id = mailer.send(
        to=invoice.customer_email,
        template="invoice",
        context=invoice.render_context(),
        idempotency_key=f"invoice:{invoice_id}",   # the provider dedupes too
    )

    invoice.update(sent_at=utcnow(), provider_message_id=message_id)
```

Two protections, deliberately: the local check handles the common case, and the provider's idempotency key handles the crash between `send` and `update`.

**Enqueue after commit, not inside the transaction:**

```python
with db.transaction():
    order = Order.create(...)
    db.after_commit(lambda: send_invoice.enqueue(order.invoice_id))
```

## Notes

- The most common job-system bug is enqueueing from inside an uncommitted transaction. The worker is fast enough to look for a row that does not exist yet, and the job fails with "not found" only under load.
- Exponential backoff without jitter causes retry storms to synchronize. Always add jitter.
- Long-running jobs should checkpoint. A 40-minute export that fails at minute 39 and restarts from zero will never complete under any retry policy.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [nimadorostkar](https://github.com/nimadorostkar)
- **Source:** [nimadorostkar/Claude-Skills-collection](https://github.com/nimadorostkar/Claude-Skills-collection)
- **License:** MIT
- **Homepage:** https://github.com/nimadorostkar/Claude-Skills-collection

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-nimadorostkar-claude-skills-collection-background-jobs
- Seller: https://agentstack.voostack.com/s/nimadorostkar
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
