Trigger Dev Tasks
Build production-grade background jobs and async workflows with ease
✨ The solution you've been looking for
Use this skill when writing, designing, or optimizing Trigger.dev background tasks and workflows. This includes creating reliable async tasks, implementing AI workflows, setting up scheduled jobs, structuring complex task hierarchies with subtasks, configuring build extensions for tools like ffmpeg or Puppeteer/Playwright, and handling task schemas with Zod validation.
See It In Action
Interactive preview & real-world examples
AI Conversation Simulator
See how users interact with this skill
User Prompt
Help me create a Trigger.dev task for processing payments that won't double-charge customers if it retries
Skill Processing
Analyzing request...
Agent Response
A production-ready payment task with idempotency keys, proper error handling, and retry configuration
Quick Start (3 Steps)
Get up and running in minutes
Install
claude-code skill install trigger-dev-tasks
claude-code skill install trigger-dev-tasksConfig
First Trigger
@trigger-dev-tasks helpCommands
| Command | Description | Required Args |
|---|---|---|
| @trigger-dev-tasks reliable-payment-processing | Create idempotent payment tasks that handle retries and failures gracefully | None |
| @trigger-dev-tasks complex-workflow-orchestration | Structure multi-step workflows with parent-child task hierarchies and conditional logic | None |
| @trigger-dev-tasks scheduled-data-processing | Set up recurring jobs for data processing, cleanup, or reporting tasks | None |
Typical Use Cases
Reliable Payment Processing
Create idempotent payment tasks that handle retries and failures gracefully
Complex Workflow Orchestration
Structure multi-step workflows with parent-child task hierarchies and conditional logic
Scheduled Data Processing
Set up recurring jobs for data processing, cleanup, or reporting tasks
Overview
Trigger.dev Task Expert
You are an expert Trigger.dev developer specializing in building production-grade background job systems. Tasks deployed to Trigger.dev run in Node.js 21+ and use the @trigger.dev/sdk package.
Critical Rules
- Always use
@trigger.dev/sdk- Never use@trigger.dev/sdk/v3or deprecatedclient.defineJobpattern - Never use
node-fetch- Use the built-infetchfunction - Export all tasks - Every task must be exported, including subtasks
- Never wrap wait/trigger calls in Promise.all -
triggerAndWait,batchTriggerAndWait, andwait.*calls cannot be wrapped inPromise.allorPromise.allSettled
Basic Task Pattern
1import { task } from "@trigger.dev/sdk";
2
3export const processData = task({
4 id: "process-data",
5 retry: {
6 maxAttempts: 10,
7 factor: 1.8,
8 minTimeoutInMs: 500,
9 maxTimeoutInMs: 30_000,
10 },
11 run: async (payload: { userId: string; data: any[] }) => {
12 console.log(`Processing ${payload.data.length} items`);
13 return { processed: payload.data.length };
14 },
15});
Schema Task (with validation)
1import { schemaTask } from "@trigger.dev/sdk";
2import { z } from "zod";
3
4export const validatedTask = schemaTask({
5 id: "validated-task",
6 schema: z.object({
7 name: z.string(),
8 email: z.string().email(),
9 }),
10 run: async (payload) => {
11 // Payload is automatically validated and typed
12 return { message: `Hello ${payload.name}` };
13 },
14});
Triggering Tasks
From Backend Code (type-only import to prevent dependency leakage)
1import { tasks } from "@trigger.dev/sdk";
2import type { processData } from "./trigger/tasks";
3
4const handle = await tasks.trigger<typeof processData>("process-data", {
5 userId: "123",
6 data: [{ id: 1 }],
7});
From Inside Tasks
1export const parentTask = task({
2 id: "parent-task",
3 run: async (payload) => {
4 // Trigger and wait - returns Result object, NOT direct output
5 const result = await childTask.triggerAndWait({ data: "value" });
6 if (result.ok) {
7 console.log("Output:", result.output);
8 } else {
9 console.error("Failed:", result.error);
10 }
11
12 // Or unwrap directly (throws on error)
13 const output = await childTask.triggerAndWait({ data: "value" }).unwrap();
14 },
15});
Idempotency (Critical for Retries)
Always use idempotency keys when triggering tasks from inside other tasks:
1import { idempotencyKeys } from "@trigger.dev/sdk";
2
3export const paymentTask = task({
4 id: "process-payment",
5 run: async (payload: { orderId: string }) => {
6 // Scoped to current run - survives retries
7 const key = await idempotencyKeys.create(`payment-${payload.orderId}`);
8
9 await chargeCustomer.trigger(payload, {
10 idempotencyKey: key,
11 idempotencyKeyTTL: "24h",
12 });
13 },
14});
Trigger Options
1await myTask.trigger(payload, {
2 delay: "1h", // Delay execution
3 ttl: "10m", // Cancel if not started within TTL
4 idempotencyKey: key,
5 queue: "my-queue",
6 machine: "large-1x", // micro, small-1x, small-2x, medium-1x, medium-2x, large-1x, large-2x
7 maxAttempts: 3,
8 tags: ["user_123"], // Max 10 tags
9 debounce: { // Consolidate rapid triggers
10 key: "unique-key",
11 delay: "5s",
12 mode: "trailing", // "leading" (default) or "trailing"
13 },
14});
Debouncing
Consolidate multiple triggers into a single execution:
1// Rapid triggers with same key = single execution
2await myTask.trigger({ userId: "123" }, {
3 debounce: {
4 key: "user-123-update",
5 delay: "5s",
6 },
7});
8
9// Trailing mode: use payload from LAST trigger
10await myTask.trigger({ data: "latest" }, {
11 debounce: {
12 key: "my-key",
13 delay: "10s",
14 mode: "trailing",
15 },
16});
Use cases: user activity updates, webhook deduplication, search indexing, notification batching.
Batch Triggering
Up to 1,000 items per batch, 3MB per payload:
1const results = await myTask.batchTriggerAndWait([
2 { payload: { userId: "1" } },
3 { payload: { userId: "2" } },
4]);
5
6for (const result of results) {
7 if (result.ok) console.log(result.output);
8}
Machine Presets
| Preset | vCPU | Memory |
|---|---|---|
| micro | 0.25 | 0.25GB |
| small-1x | 0.5 | 0.5GB |
| small-2x | 1 | 1GB |
| medium-1x | 1 | 2GB |
| medium-2x | 2 | 4GB |
| large-1x | 4 | 8GB |
| large-2x | 8 | 16GB |
Design Principles
- Break complex workflows into subtasks that can be independently retried and made idempotent
- Don’t over-complicate - Sometimes
Promise.allSettledinside a single task is better than many subtasks (each task has dedicated process and is charged by millisecond) - Always configure retries - Set appropriate
maxAttemptsbased on the operation - Use idempotency keys - Especially for payment/critical operations
- Group related subtasks - Keep subtasks only used by one parent in the same file, don’t export them
- Use logger - Log at key execution points with
logger.info(),logger.error(), etc.
Reference Documentation
For detailed documentation on specific topics, read these files:
basic-tasks.md- Task basics, triggering, waitsadvanced-tasks.md- Tags, queues, concurrency, metadata, error handlingscheduled-tasks.md- Cron schedules, declarative and imperativerealtime.md- Real-time subscriptions, streams, React hooksconfig.md- trigger.config.ts, build extensions (Prisma, Playwright, FFmpeg, etc.)
What Users Are Saying
Real feedback from the community
Environment Matrix
Dependencies
Framework Support
Context Window
Security & Privacy
Information
- Author
- triggerdotdev
- Updated
- 2026-01-30
- Category
- productivity-tools
Related Skills
Trigger Dev Tasks
Use this skill when writing, designing, or optimizing Trigger.dev background tasks and workflows. …
View Details →Backend Dev Guidelines
Comprehensive backend development guide for Langfuse's Next.js 14/tRPC/Express/TypeScript monorepo. …
View Details →Backend Dev Guidelines
Comprehensive backend development guide for Langfuse's Next.js 14/tRPC/Express/TypeScript monorepo. …
View Details →