set-up-background-jobs
Skill7 starsChanged 18 days agoMITView on GitHub
Use when a backend must do work outside the request (email, webhooks, imports, schedules) or publish events reliably — adds a Postgres-backed queue (pg-boss, River, procrastinate), the transactional outbox, idempotent handlers, retries with dead letter, cron jobs.
- Reads credentials
- Installs packages
1 other project uses a version of this.
Adopted by
Most recently taken up by
- VelimirMueller/claude-skillsword for word, first seen Oct 11, 2026
Other versions1 project uses a version of this.
Word for word · 1
- VelimirMueller/claude-skills★ 7100% same
Edited · 0
None found.
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository156 other files it gives its agents.
- skills/swift/swiftui-design-principles/AGENTS.mdAGENTS.md
- skills/swift/ios-code-audit/CLAUDE.mdCLAUDE.md
- skills/swift/swift-focusengine-pro/llms.txtllms.txt
- build-llm-seamSkill
- build-mcp-serverSkill
- build-rag-pipelineSkill
- secure-llm-featuresSkill
- set-up-llm-evalsSkill
- build-nextjs-backendSkill
- build-supabase-edge-functionSkill
- configure-backend-testsSkill
- design-http-apiSkill
- harden-backendSkill
- scaffold-fastapi-serviceSkill
- scaffold-go-serviceSkill
- scaffold-hono-serviceSkill
- secure-supabase-rlsSkill
- set-up-backend-authSkill
- set-up-databaseSkill
- set-up-nextjs-supabase-authSkill
- set-up-observabilitySkill
- set-up-supabaseSkill
- build-cliSkill
- release-cliSkill
- set-up-dev-toolchainSkill
- audit-securitySkill
- audit-toolchainSkill
- extend-skillsetSkill
- promote-releaseSkill
- set-up-stack-profileSkill
- write-commit-messagesSkill
- write-pull-requestsSkill
- analyze-complexitySkill
- apply-algorithmsSkill
- apply-design-patternsSkill
- apply-design-principlesSkill
- apply-solidSkill
- choose-data-structureSkill
- debug-systematicallySkill
- enforce-dependency-ruleSkill
- refactor-safelySkill
- slice-and-estimateSkill
- write-clean-testsSkill
- write-readable-codeSkill
- clean-frontend-scaffoldingSkill
- configure-accessibilitySkill
- configure-analyticsSkill
- configure-ciSkill
- configure-error-trackingSkill
- configure-lintingSkill
- configure-test-stackSkill
- configure-typescriptSkill
- create-moduleSkill
- optimize-performanceSkill
- scaffold-frontend-projectSkill
- set-up-authSkill
- set-up-design-systemSkill
- set-up-document-headSkill
- set-up-error-boundariesSkill
- set-up-feature-flagsSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 2 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 10
Default: a queue that lives in the Postgres you already run.
- Distinctive: line 28
No queue, no outbox: full setup (steps 3 to 7).
- Very specific: line 44
All three need a direct Postgres connection for workers (no transaction-mode pooler): they use LISTEN/NOTIFY and locks that a pooler drops.
- Very specific: line 54
If the package manager skips peers (npm --legacy-peer-deps), install @opentelemetry/api by hand: without it import 'pg-boss' throws …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Set Up Background Jobs
Rules and rationale: jobs-patterns.md. Code per track and migrations: jobs-track-patterns.md. Database seam and transactions: set-up-database. Layer paths: service-layout.md. Versions: stack-versions.md.
Default: a queue that lives in the Postgres you already run. A job is inserted in the same transaction as the write that causes it, so both exist or neither does.
1. Audit (change nothing)
cat .claude/stack-profile.md ~/.claude/stack-profile.md 2>/dev/null # backend.track, database.{engine,orm,host}, observability, hosting
ls src/platform/queue.ts internal/transport/jobs src/*/transport/jobs.py src/worker.ts cmd/*/worker* 2>/dev/null
grep -rnE "\"(bullmq|bull|agenda|pg-boss|graphile-worker|bee-queue)\"" package.json 2>/dev/null
grep -nE "riverqueue|asynq|machinery" go.mod 2>/dev/null
grep -nE "celery|rq|arq|dramatiq|procrastinate|taskiq" pyproject.toml requirements*.txt 2>/dev/null
grep -rnE "setTimeout\(|setInterval\(|time\.AfterFunc|asyncio\.create_task|BackgroundTasks|go func\(" src internal 2>/dev/null | head # work done after the response, unrecorded
grep -rniE "redis|sqs|nats|rabbit|kafka" compose.yaml docker-compose.yml .env.example 2>/dev/null | headRecord: fire-and-forget work in a handler (lost on restart), cron implemented in an OS crontab or setInterval, an existing broker and who runs it, writes followed by a publish in the same function (dual write).
2. Decide
- No queue, no outbox: full setup (steps 3 to 7).
- A Postgres-backed queue exists: add only the missing parts (retry config, dead letter, idempotency, retention, outbox).
- Redis or a broker exists and is already operated by the team: keep it for existing flows; use the outbox so new events leave Postgres reliably; do not add a second queue system without a reason.
backend.track: supabasewith no own server:pgmqandpg_cronextensions or Edge Function triggers apply; see set-up-supabase. Next.js on serverless hosting cannot run a long-lived worker: use the host's cron plus a separate worker service.- Everything present and step 7 passes: report "already in place" and stop.
Graduate beyond Postgres only on the triggers in jobs-patterns.md, section "When to leave Postgres".
3. Detect track
backend.track | Queue | Why this one |
hono | pg-boss | Typed, dead-letter queues, backoff, tz-aware cron, Drizzle adapter; 80 releases in 12 months, latest 2026-10-08. graphile-worker (0.x, 5 releases) is the alternative when jobs are enqueued from SQL triggers |
go | River | Go-native, InsertTx with pgx, unique jobs, periodic jobs, typed args; v0.49 active |
fastapi | procrastinate | Async, psycopg 3, can enlist in the request's transaction, periodic tasks; 3.10 active. pgqueuer 1.5 is the younger alternative |
All three need a direct Postgres connection for workers (no transaction-mode pooler): they use LISTEN/NOTIFY and locks that a pooler drops.
4. Install only what is missing
pnpm add pg-boss @opentelemetry/api # hono: pg-boss imports @opentelemetry/api at runtime (peer)
go get github.com/riverqueue/river github.com/riverqueue/river/riverdriver/riverpgxv5 # go: v0.49 needs Go 1.26+
uv add procrastinate # fastapi (psycopg[binary,pool] is already installed: scaffold and set-up-database ship it)If the package manager skips peers (npm --legacy-peer-deps), install @opentelemetry/api by hand: without it import 'pg-boss' throws ERR_MODULE_NOT_FOUND.
5. Generate the seams
- Queue seam, one file owns the vendor: TS
src/platform/queue.ts, Gointernal/transport/jobs/, Pythonsrc/<pkg>/platform/queue.py. A typed registry of job names and payloads lives there, nowhere else. - Consumer (a non-HTTP transport): TS
src/transport/jobs/*.ts, Gointernal/transport/jobs/jobs.go, Pythonsrc/<pkg>/transport/jobs.py. A handler parses the payload, calls one service method, returns or throws. No business rule inside. - Producers call the seam with the open transaction handle (
enqueue(tx, ...),InsertTx,configure(connection=...)). Code per track in jobs-track-patterns.md. - Outbox, only for events that leave the service (broker, webhook, another system):
outboxtable, relay job,Publisherinterface. A job for this service's own work needs no outbox: the queue row is the outbox. - Queue settings, one place: retry limit and backoff, expiry, dead-letter queue, retention. Defaults and why: jobs-patterns.md.
- Schedules: declared in code next to the queue config, with an explicit time zone (
UTCunless a business rule says otherwise). - Schema install belongs to the migration step (migration-patterns.md), not to app startup:
pg-boss migrate(setmigrate: falseat runtime), River SQL dumped into goose withriver migrate-get, procrastinate schema inside an Alembic revision.
6. Wire
- Worker is a separate entry point of the same image (
node dist/worker.mjs,cmd/<svc>/worker,procrastinate worker), scaled and deployed apart from the API. A tiny service may run the worker in the API process; then give the pool enough connections for both. - Graceful shutdown: on SIGTERM stop fetching, wait for running jobs up to a timeout shorter than the platform's kill timeout, then exit.
- Config via config.md:
DATABASE_URL(direct URL for the worker), concurrency, timeouts. Runtime role grants: jobs-track-patterns.md. - Observability: log job name, id, attempt and outcome with the trace id (logging-contract.md); alert on dead-letter growth and on the oldest ready job's age (observability.md).
- Cleanup: retention for finished jobs and a scheduled purge of the idempotency table.
7. Verify
# 1. atomicity: enqueue inside a transaction that rolls back -> no job
# 2. retries: a handler that throws runs again, with growing delay; after the limit the job is in the dead-letter state
# 3. idempotency: run one job twice on purpose -> one external effect
# 4. schedule: next run is listed in the queue's schedule table with the right time zonePer track the exact commands are in jobs-track-patterns.md, section "Verify". Pass criteria: a rolled-back enqueue leaves zero jobs; a failing handler ends in the dead-letter state (dead-letter queue, discarded, failed); the second run of the same job id changes nothing; SELECT on the queue table shows the schedule.
References
- jobs-patterns.md: why Postgres first, outbox, idempotency, retries, schedules, retention, graduation.
- jobs-track-patterns.md: pg-boss, River, procrastinate code and install steps.
- ../design-http-api/api-contract-patterns.md: idempotency keys on the HTTP side.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

