Tasks Overview
Tasks are the core building block of Trigger.dev. A task is an async function with a unique ID that can be triggered, queued, retried, and monitored.
Hello World Task
ts
// /trigger/hello-world.ts
import { task } from "@trigger.dev/sdk";
const helloWorld = task({
id: "hello-world",
run: async (payload: { message: string }) => {
console.log(payload.message);
return { success: true };
},
});Trigger it from your backend:
ts
import { helloWorld } from "./trigger/hello-world";
const handle = await helloWorld.trigger({ message: "Hello world!" });Task Options
id (required)
Unique string identifier for the task. Used for triggering, management, and dashboard views.
run function
Your async task code. Receives:
- payload — the data passed when triggered
{ ctx }— context about the run
Return value becomes the task output (must be JSON serializable).
retry
ts
retry: {
maxAttempts: 10,
factor: 1.8,
minTimeoutInMs: 500,
maxTimeoutInMs: 30_000,
randomize: false,
}Default: 3 retries. A task is retried if an error is thrown.
queue
ts
queue: {
concurrencyLimit: 1, // max parallel runs
}machine
ts
machine: {
preset: "large-1x", // 4 vCPU, 8 GB RAM
}Available presets: micro, small-1x, small-2x, medium-1x, medium-2x, large-1x, large-2x.
maxDuration
ts
maxDuration: 300, // 300 seconds = 5 minutesPrevents a task from running too long.
Lifecycle Hooks
Per-task hooks
ts
export const myTask = task({
id: "my-task",
onStartAttempt: async ({ ctx }) => { /* before each attempt */ },
onWait: async ({ ctx }) => { /* when task pauses */ },
onResume: async ({ ctx }) => { /* when task resumes */ },
onSuccess: async ({ ctx, output }) => { /* after success */ },
onFailure: async ({ ctx, error }) => { /* after all retries exhausted */ },
onComplete: async ({ ctx }) => { /* success or failure */ },
onCancel: async ({ ctx }) => { /* when cancelled */ },
run: async (payload, { ctx }) => { /* ... */ },
});middleware and locals
The middleware system runs at the top level, before and after all lifecycle hooks:
ts
import { locals, tasks } from "@trigger.dev/sdk";
const DbLocal = locals.create<{ connect: () => Promise<void>; disconnect: () => Promise<void> }>("db");
tasks.middleware("db", async ({ ctx, payload, next }) => {
const db = locals.set(DbLocal, { /* ... */ });
await db.connect();
await next();
await db.disconnect();
});catchError
Control error handling and retry behavior:
ts
export const myTask = task({
id: "my-task",
catchError: async (error, ctx) => {
if (error.message.includes("rate limit")) {
return { retry: { delay: "60s" } };
}
throw error; // re-throw to use default retry
},
run: async (payload) => { /* ... */ },
});Global Lifecycle Hooks
Register in init.ts at the root of your trigger directory:
ts
// /trigger/init.ts
import { tasks } from "@trigger.dev/sdk";
tasks.onStart(({ ctx, payload, task }) => {
console.log("Run started", ctx.run.id);
});
tasks.onSuccess(({ ctx, output }) => {
console.log("Run finished", ctx.run.id);
});
tasks.onFailure(({ ctx, error }) => {
console.log("Run failed", ctx.run.id, error);
});Task Types
- Regular tasks — standard async tasks
- Scheduled tasks — cron-based recurring tasks
- Schema tasks — tasks with validated input schemas