This task sends an onboarding email sequence to a user. Each email is wrapped in retry.onThrow so
that only the failed send is retried — not the entire task. Between emails, wait.for suspends
the task for a configurable duration. During the wait, the task is fully paused and consumes zero
resources.
Calling await wait.for({ days: 3 }) suspends the task entirely. No compute is used during the
wait. Once the duration elapses, the task resumes exactly where it left off.
// Wait for a specific durationawait wait.for({ days: 3 });await wait.for({ hours: 12 });await wait.for({ minutes: 30 });
retry.onThrow wraps a code block with its own retry logic. If the block throws, only that block
is retried — any work already done outside the block (earlier emails in the sequence) is not
repeated.
const result = await retry.onThrow( async ({ attempt }) => { // attempt starts at 1 const response = await someApiCall(); if (!response.ok) throw new Error("API call failed"); return response.data; }, { maxAttempts: 3 });
Compare this with task-level retry (set in the retry field of task({})), which retries the
entire run from the beginning. Use retry.onThrow when you want fine-grained retries within a
long-running task.
During testing, the wait.for call will pause the task for the configured duration. If you want
to skip the wait in development, you can reduce the duration (e.g. { seconds: 5 }) while
testing and restore it before deploying.