Background jobs, domain events, and side effects
**When to use:** Queues and workers, domain event publishers, async notifications or projections, or **not** doing that work inside HTTP handlers.
Best use case
Background jobs, domain events, and side effects is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
**When to use:** Queues and workers, domain event publishers, async notifications or projections, or **not** doing that work inside HTTP handlers.
Teams using Background jobs, domain events, and side effects should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/async-jobs-and-events/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How Background jobs, domain events, and side effects Compares
| Feature / Agent | Background jobs, domain events, and side effects | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
**When to use:** Queues and workers, domain event publishers, async notifications or projections, or **not** doing that work inside HTTP handlers.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
Related Guides
AI Agents for Coding
Browse AI agent skills for coding, debugging, testing, refactoring, code review, and developer workflows across Claude, Cursor, and Codex.
Cursor vs Codex for AI Workflows
Compare Cursor and Codex for AI coding workflows, repository assistance, debugging, refactoring, and reusable developer skills.
AI Agents for Marketing
Discover AI agents for marketing workflows, from SEO and content production to campaign research, outreach, and analytics.
SKILL.md Source
# Background jobs, domain events, and side effects **When to use:** Queues and workers, domain event publishers, async notifications or projections, or **not** doing that work inside HTTP handlers. ## Side effects and eventing - Domain code emits **domain events** through **domain-level publisher** abstractions (ports), not ad-hoc calls from use-cases to email/HTTP/Slack. - **Workers** handle notifications, integrations, projections, and other I/O **asynchronously**. - **Do not** orchestrate side effects (fan-out integrations, “fire and forget” HTTP, etc.) inside HTTP handlers — enqueue / publish and return. ## Async and background tasks - Put **IDs** or opaque storage keys in job payloads — not full mutable entities. - **Re-fetch** authoritative state inside the worker before acting. - Make **stale or deleted** entities an explicit outcome (skip, dead-letter, or record failure) instead of assuming rows still exist. - For **transactional domain events**, write through the **`OutboxWriter`** port in `@domain/events` (for example `createOutboxWriter` from `@platform/db-postgres`) instead of inserting outbox rows directly. - For **high-volume or otherwise non-transactional producers** whose upstream write is already durable, publish directly through **`createEventsPublisher(queuePublisher)`** into `domain-events` instead of persisting an outbox row only to forward it. - Domain-event consumers should act as **dispatchers**: publish downstream topic tasks or start workflows, but do not run synchronous business logic inline inside the event handler. - Extend the repo’s existing async rails instead of inventing new ones: BullMQ-backed queue workers live in `apps/workers`, and durable multi-step workflows live in the Temporal-backed `apps/workflows` app. - Queue topics may own several related **lower-kebab-case** task names; one worker module owns the topic and dispatches by task name. - Queue publication should expose logical **dedupe/debounce** keyed by the relevant entity identity when the transport supports it. - Use **queue topics** for single-step tasks and the **workflow abstraction** for long-running or multi-step orchestration. - For reliability async contracts, include both `organizationId` and `projectId` in domain-event payloads, topic/task payloads, and workflow inputs by default. Exceptions: `MagicLinkEmailRequested`, `InvitationEmailRequested`, `UserDeletionRequested`, the `domain-events` topic payload, the `magic-link-email` topic payload, the `invitation-email` topic payload, and the `user-deletion` topic payload. - When BullMQ delay is the chosen debounce mechanism, key the delayed job by the logical entity identity so newer writes replace or reschedule the pending job. - When a delayed queue topic semantically marks a lifecycle edge, let the delayed task publish a domain event through the appropriate rail after the delay elapses: use `OutboxWriter` for transactional boundaries and direct `EventsPublisher` publication for non-transactional or high-volume worker flows. Downstream side effects should run from the domain-event consumers rather than inline in the delayed task. ## New infrastructure dependencies When adding a new external system the product talks to: 1. Add a concrete provider package in `packages/platform/*-<provider>`. 2. **Wire** it in the app composition root from **environment-driven** config. 3. Change **domain** only if **business rules** change — not for every new adapter. For env var naming when wiring config, see [env-configuration](../env-configuration/SKILL.md). For layer rules, see [architecture-boundaries](../architecture-boundaries/SKILL.md).
Related Skills
web-frontend
apps/web UI — routes, @repo/ui, TanStack Start server functions and collections, forms, Tailwind layout rules, design-system updates, and useEffect / useMountEffect policy.
toolchain-commands
Installing dependencies, running dev/build/test/lint, filtering packages, single-test runs, git hooks, preparing a clone (.env.development / .env.test), or Docker-backed local services and dev servers.
testing
Writing or debugging tests, choosing unit vs integration style, Postgres/ClickHouse tests, regenerating ClickHouse test schema, or exporting test helpers from packages without pulling test code into production bundles.
gh-issue
Create clear, actionable GitHub issues for bugs, features, and improvements. Issues are primarily consumed by LLMs, so optimize for agent readability and actionability.
env-configuration
Adding or reading env vars, updating .env.example, or validating config at startup with parseEnv / parseEnvOptional.
effect-and-errors
Composing Effect programs, domain errors, HttpError, repository error types, or error propagation at HTTP boundaries.
database-postgres
Drizzle schema, repositories, RLS, SqlClient wiring, Postgres migrations, psql / reset, or platform mappers (toDomain* / toInsertRow).
database-clickhouse-weaviate
ClickHouse queries, Goose migrations, chdb test schema, Weaviate collections/migrations, or telemetry storage paths.
code-style
Biome formatting, import style, strict TypeScript, naming (including React file names), or generated files.
authentication
Sessions, sign-in/sign-up flows, OAuth, magic links, or organization context on the session.
Web app frontend (`apps/web`)
**When to use:** `apps/web` UI — routes, `@repo/ui`, TanStack Start server functions and collections, forms, Tailwind layout rules, design-system updates, and **`useEffect` / `useMountEffect` policy**.
Toolchain, commands, and CI
**When to use:** Installing dependencies, running dev/build/test/lint, filtering packages, single-test runs, git hooks, preparing a clone (`.env.development` / `.env.test`), or **Docker-backed local services and dev servers**.