# Scheduled tasks (cron) Recurring tasks using cron. For one-off future runs, use the **delay** option. ## Define a scheduled task ```ts import { schedules } from "@trigger.dev/sdk"; export const task = schedules.task({ id: "first-scheduled-task", run: async (payload) => { payload.timestamp; // Date (scheduled time, UTC) payload.lastTimestamp; // Date | undefined payload.timezone; // IANA, e.g. "America/New_York" (default "UTC") payload.scheduleId; // string payload.externalId; // string | undefined payload.upcoming; // Date[] payload.timestamp.toLocaleString("en-US", { timeZone: payload.timezone }); }, }); ``` > Scheduled tasks need at least one schedule attached to run. ## Attach schedules **Declarative (sync on dev/deploy):** ```ts schedules.task({ id: "every-2h", cron: "0 */2 * * *", // UTC run: async () => {}, }); schedules.task({ id: "tokyo-5am", cron: { pattern: "0 5 * * *", timezone: "Asia/Tokyo", environments: ["PRODUCTION", "STAGING"] }, run: async () => {}, }); ``` **Imperative (SDK or dashboard):** ```ts await schedules.create({ task: task.id, cron: "0 0 * * *", timezone: "America/New_York", // DST-aware externalId: "user_123", deduplicationKey: "user_123-daily", // updates if reused }); ``` ### Dynamic / multi-tenant example ```ts // /trigger/reminder.ts export const reminderTask = schedules.task({ id: "todo-reminder", run: async (p) => { if (!p.externalId) throw new Error("externalId is required"); const user = await db.getUser(p.externalId); await sendReminderEmail(user); }, }); ``` ```ts // app/reminders/route.ts export async function POST(req: Request) { const data = await req.json(); return Response.json( await schedules.create({ task: reminderTask.id, cron: "0 8 * * *", timezone: data.timezone, externalId: data.userId, deduplicationKey: `${data.userId}-reminder`, }) ); } ``` ## Cron syntax (no seconds) ``` * * * * * | | | | └ day of week (0–7 or 1L–7L; 0/7=Sun; L=last) | | | └── month (1–12) | | └──── day of month (1–31 or L) | └────── hour (0–23) └──────── minute (0–59) ``` ## When schedules won't trigger - **Dev:** only when the dev CLI is running. - **Staging/Production:** only for tasks in the **latest deployment**. ## SDK management (quick refs) ```ts await schedules.retrieve(id); await schedules.list(); await schedules.update(id, { cron: "0 0 1 * *", externalId: "ext", deduplicationKey: "key" }); await schedules.deactivate(id); await schedules.activate(id); await schedules.del(id); await schedules.timezones(); // list of IANA timezones ``` ## Dashboard Create/attach schedules visually (Task, Cron pattern, Timezone, Optional: External ID, Dedup key, Environments). Test scheduled tasks from the **Test** page.