trigger-dev-tasks
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTrigger.dev Task Expert
Trigger.dev 任务专家
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 package.
@trigger.dev/sdk你是一位专注于构建生产级后台作业系统的Trigger.dev开发专家。部署到Trigger.dev的任务运行在Node.js 21+环境中,并使用包。
@trigger.dev/sdkCritical Rules
关键规则
- Always use - Never use
@trigger.dev/sdkor deprecated@trigger.dev/sdk/v3patternclient.defineJob - Never use - Use the built-in
node-fetchfunctionfetch - Export all tasks - Every task must be exported, including subtasks
- Never wrap wait/trigger calls in Promise.all - ,
triggerAndWait, andbatchTriggerAndWaitcalls cannot be wrapped inwait.*orPromise.allPromise.allSettled
- 始终使用- 切勿使用
@trigger.dev/sdk或已弃用的@trigger.dev/sdk/v3模式client.defineJob - 切勿使用- 使用内置的
node-fetch函数fetch - 导出所有任务 - 每个任务都必须导出,包括子任务
- 不要将wait/trigger调用包装在Promise.all中 - 、
triggerAndWait和batchTriggerAndWait调用不能被包装在wait.*或Promise.all中Promise.allSettled
Basic Task Pattern
基础任务模式
ts
import { task } from "@trigger.dev/sdk";
export const processData = task({
id: "process-data",
retry: {
maxAttempts: 10,
factor: 1.8,
minTimeoutInMs: 500,
maxTimeoutInMs: 30_000,
},
run: async (payload: { userId: string; data: any[] }) => {
console.log(`Processing ${payload.data.length} items`);
return { processed: payload.data.length };
},
});ts
import { task } from "@trigger.dev/sdk";
export const processData = task({
id: "process-data",
retry: {
maxAttempts: 10,
factor: 1.8,
minTimeoutInMs: 500,
maxTimeoutInMs: 30_000,
},
run: async (payload: { userId: string; data: any[] }) => {
console.log(`Processing ${payload.data.length} items`);
return { processed: payload.data.length };
},
});Schema Task (with validation)
带验证的模式任务
ts
import { schemaTask } from "@trigger.dev/sdk";
import { z } from "zod";
export const validatedTask = schemaTask({
id: "validated-task",
schema: z.object({
name: z.string(),
email: z.string().email(),
}),
run: async (payload) => {
// Payload is automatically validated and typed
return { message: `Hello ${payload.name}` };
},
});ts
import { schemaTask } from "@trigger.dev/sdk";
import { z } from "zod";
export const validatedTask = schemaTask({
id: "validated-task",
schema: z.object({
name: z.string(),
email: z.string().email(),
}),
run: async (payload) => {
// Payload is automatically validated and typed
return { message: `Hello ${payload.name}` };
},
});Triggering Tasks
触发任务
From Backend Code (type-only import to prevent dependency leakage)
从后端代码触发(仅类型导入以避免依赖泄漏)
ts
import { tasks } from "@trigger.dev/sdk";
import type { processData } from "./trigger/tasks";
const handle = await tasks.trigger<typeof processData>("process-data", {
userId: "123",
data: [{ id: 1 }],
});ts
import { tasks } from "@trigger.dev/sdk";
import type { processData } from "./trigger/tasks";
const handle = await tasks.trigger<typeof processData>("process-data", {
userId: "123",
data: [{ id: 1 }],
});From Inside Tasks
从任务内部触发
ts
export const parentTask = task({
id: "parent-task",
run: async (payload) => {
// Trigger and wait - returns Result object, NOT direct output
const result = await childTask.triggerAndWait({ data: "value" });
if (result.ok) {
console.log("Output:", result.output);
} else {
console.error("Failed:", result.error);
}
// Or unwrap directly (throws on error)
const output = await childTask.triggerAndWait({ data: "value" }).unwrap();
},
});ts
export const parentTask = task({
id: "parent-task",
run: async (payload) => {
// Trigger and wait - returns Result object, NOT direct output
const result = await childTask.triggerAndWait({ data: "value" });
if (result.ok) {
console.log("Output:", result.output);
} else {
console.error("Failed:", result.error);
}
// Or unwrap directly (throws on error)
const output = await childTask.triggerAndWait({ data: "value" }).unwrap();
},
});Idempotency (Critical for Retries)
幂等性(重试的关键)
Always use idempotency keys when triggering tasks from inside other tasks:
ts
import { idempotencyKeys } from "@trigger.dev/sdk";
export const paymentTask = task({
id: "process-payment",
run: async (payload: { orderId: string }) => {
// Scoped to current run - survives retries
const key = await idempotencyKeys.create(`payment-${payload.orderId}`);
await chargeCustomer.trigger(payload, {
idempotencyKey: key,
idempotencyKeyTTL: "24h",
});
},
});在从其他任务内部触发任务时,始终使用幂等键:
ts
import { idempotencyKeys } from "@trigger.dev/sdk";
export const paymentTask = task({
id: "process-payment",
run: async (payload: { orderId: string }) => {
// Scoped to current run - survives retries
const key = await idempotencyKeys.create(`payment-${payload.orderId}`);
await chargeCustomer.trigger(payload, {
idempotencyKey: key,
idempotencyKeyTTL: "24h",
});
},
});Trigger Options
触发选项
ts
await myTask.trigger(payload, {
delay: "1h", // Delay execution
ttl: "10m", // Cancel if not started within TTL
idempotencyKey: key,
queue: "my-queue",
machine: "large-1x", // micro, small-1x, small-2x, medium-1x, medium-2x, large-1x, large-2x
maxAttempts: 3,
tags: ["user_123"], // Max 10 tags
debounce: { // Consolidate rapid triggers
key: "unique-key",
delay: "5s",
mode: "trailing", // "leading" (default) or "trailing"
},
});ts
await myTask.trigger(payload, {
delay: "1h", // 延迟执行
ttl: "10m", // 如果在TTL内未启动则取消
idempotencyKey: key,
queue: "my-queue",
machine: "large-1x", // micro, small-1x, small-2x, medium-1x, medium-2x, large-1x, large-2x
maxAttempts: 3,
tags: ["user_123"], // 最多10个标签
debounce: { // 合并快速触发
key: "unique-key",
delay: "5s",
mode: "trailing", // "leading"(默认)或"trailing"
},
});Debouncing
防抖
Consolidate multiple triggers into a single execution:
ts
// Rapid triggers with same key = single execution
await myTask.trigger({ userId: "123" }, {
debounce: {
key: "user-123-update",
delay: "5s",
},
});
// Trailing mode: use payload from LAST trigger
await myTask.trigger({ data: "latest" }, {
debounce: {
key: "my-key",
delay: "10s",
mode: "trailing",
},
});Use cases: user activity updates, webhook deduplication, search indexing, notification batching.
将多次触发合并为单次执行:
ts
// 相同键的快速触发 = 单次执行
await myTask.trigger({ userId: "123" }, {
debounce: {
key: "user-123-update",
delay: "5s",
},
});
// trailing模式:使用最后一次触发的负载
await myTask.trigger({ data: "latest" }, {
debounce: {
key: "my-key",
delay: "10s",
mode: "trailing",
},
});使用场景:用户活动更新、Webhook去重、搜索索引、通知批处理。
Batch Triggering
批量触发
Up to 1,000 items per batch, 3MB per payload:
ts
const results = await myTask.batchTriggerAndWait([
{ payload: { userId: "1" } },
{ payload: { userId: "2" } },
]);
for (const result of results) {
if (result.ok) console.log(result.output);
}每批最多1000个项目,每个负载最大3MB:
ts
const results = await myTask.batchTriggerAndWait([
{ payload: { userId: "1" } },
{ payload: { userId: "2" } },
]);
for (const result of results) {
if (result.ok) console.log(result.output);
}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 |
| 预设值 | vCPU | 内存 |
|---|---|---|
| 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 inside a single task is better than many subtasks (each task has dedicated process and is charged by millisecond)
Promise.allSettled - Always configure retries - Set appropriate based on the operation
maxAttempts - 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(), etc.logger.error()
- 将复杂工作流拆分为子任务,这些子任务可以独立重试并实现幂等
- 不要过度复杂化 - 有时在单个任务内使用比使用多个子任务更好(每个任务都有专用进程,按毫秒计费)
Promise.allSettled - 始终配置重试 - 根据操作设置合适的
maxAttempts - 使用幂等键 - 尤其是在支付/关键操作中
- 分组相关子任务 - 将仅被一个父任务使用的子任务放在同一文件中,不要导出它们
- 使用日志记录器 - 在关键执行点使用、
logger.info()等记录日志logger.error()
Reference Documentation
参考文档
For detailed documentation on specific topics, read these files:
- - Task basics, triggering, waits
basic-tasks.md - - Tags, queues, concurrency, metadata, error handling
advanced-tasks.md - - Cron schedules, declarative and imperative
scheduled-tasks.md - - Real-time subscriptions, streams, React hooks
realtime.md - - trigger.config.ts, build extensions (Prisma, Playwright, FFmpeg, etc.)
config.md
如需了解特定主题的详细文档,请阅读以下文件:
- - 任务基础、触发、等待
basic-tasks.md - - 标签、队列、并发、元数据、错误处理
advanced-tasks.md - - Cron调度、声明式和命令式
scheduled-tasks.md - - 实时订阅、流、React钩子
realtime.md - - trigger.config.ts、构建扩展(Prisma、Playwright、FFmpeg等)
config.md