Skip to main content
A run is created each time you trigger a task. It represents a single execution instance and tracks the task’s payload, status, output, and metadata throughout its lifetime.

What is a run?

A run contains:
  • A unique run ID
  • The current status
  • The payload (input data)
  • The output (result data, once complete)
  • Metadata, tags, and other contextual information

The run lifecycle

A run moves through several states during execution. The following sections describe all possible states.

Initial states

StatusDescription
Pending versionWaiting for a deployment that includes this task.
DelayedTriggered with a delay option — waiting for the delay to pass.
QueuedReady to execute, waiting in the queue for a concurrency slot.
DequeuedDequeued and being sent to a worker to begin execution.

Execution states

StatusDescription
ExecutingCurrently running on a worker.
WaitingPaused at a waitpoint (e.g. wait.for(), triggerAndWait()). Releases its concurrency slot until resumed.

Final states

StatusDescription
CompletedFinished successfully.
CanceledManually canceled.
FailedAll retry attempts exhausted.
Timed outExceeded its maxDuration.
CrashedWorker process crashed (e.g. out of memory). Not retried.
System failureAn unrecoverable internal error occurred.
ExpiredTTL elapsed before the run could start.

Attempts

An attempt is a single execution of a task within a run. A run can have multiple attempts if it fails and retries. Each attempt has:
  • A unique attempt ID
  • A status
  • An output or error
When a task fails, it is retried according to its retry settings, creating new attempts until it succeeds or exhausts the retry limit.

Boolean helpers

Run objects returned from the SDK include boolean helpers to check state without comparing status strings:
import { runs } from "@trigger.dev/sdk";

const run = await runs.retrieve("run_1234");

if (run.isCompleted) {
  console.log("Run completed successfully", run.output);
}

if (run.isFailed) {
  console.error("Run failed", run.error);
}

if (run.isExecuting) {
  console.log("Run is still executing");
}
Boolean helpers are also available when subscribing to real-time run updates:
import { runs } from "@trigger.dev/sdk";

for await (const run of runs.subscribeToRun("run_1234")) {
  if (run.isCompleted) {
    console.log("Run completed!");
    break;
  }
}

Runs API

runs.list()

List runs with optional filters:
import { runs } from "@trigger.dev/sdk";

// Paginated listing
let page = await runs.list({ limit: 20 });
for (const run of page.data) {
  console.log(run);
}
while (page.hasNextPage()) {
  page = await page.getNextPage();
}

// Async iteration (handles pagination automatically)
for await (const run of runs.list({ limit: 20 })) {
  console.log(run);
}

// With filters
const filtered = await runs.list({
  status: ["QUEUED", "EXECUTING"],
  taskIdentifier: ["my-task", "my-other-task"],
  from: new Date("2024-04-01T00:00:00Z"),
  to: new Date(),
  tag: ["tag1", "tag2"],
  batch: "batch_1234",
});

runs.retrieve()

Fetch a single run by its ID:
import { runs } from "@trigger.dev/sdk";

const run = await runs.retrieve("run_1234");
Provide the task type to get typed payload and output:
import { runs } from "@trigger.dev/sdk";
import type { myTask } from "./trigger/myTask";

const run = await runs.retrieve<typeof myTask>("run_1234");

console.log(run.payload.foo); // typed
console.log(run.output?.bar); // typed
Pass the trigger response directly to skip repeating the run ID:
import { runs, tasks } from "@trigger.dev/sdk";
import type { myTask } from "./trigger/myTask";

const response = await tasks.trigger<typeof myTask>("my-task", { foo: "bar" });
const run = await runs.retrieve(response);

runs.cancel()

Cancel a run that is queued or executing:
import { runs } from "@trigger.dev/sdk";

await runs.cancel("run_1234");
When a run is canceled:
  • Execution is stopped
  • The run is marked as canceled
  • No further retries occur
  • Any in-progress child runs are also canceled

runs.replay()

Create a new run with the same payload as a previous run:
import { runs } from "@trigger.dev/sdk";

await runs.replay("run_1234");
The new run uses the latest deployed version of the task.

runs.reschedule()

Update the delay on a run that is in the DELAYED state:
import { runs } from "@trigger.dev/sdk";

await runs.reschedule("run_1234", { delay: "1h" });

Advanced run features

Time-to-live (TTL)

Set a TTL when triggering to automatically expire a run if it has not started within the given time:
await yourTask.trigger({ foo: "bar" }, { ttl: "10m" });
Expired runs show as Expired in the dashboard.
Dev runs automatically get a 10-minute TTL. On Trigger.dev Cloud, staging and production runs receive a maximum TTL of 14 days.

Delayed runs

Schedule a run to start after a delay:
await yourTask.trigger({ foo: "bar" }, { delay: "1h" });
Delayed runs show as Delayed in the dashboard. You can reschedule or cancel them using runs.reschedule() and runs.cancel().

Idempotency keys

Prevent duplicate runs by providing an idempotency key:
await yourTask.trigger({ foo: "bar" }, { idempotencyKey: "unique-key" });
  • If a run with the same key is in progress, the new trigger is ignored and the existing run’s handle is returned.
  • If the run has already completed, the previous output or error is returned immediately.
See the wait documentation for more information.

Triggering for undeployed tasks

You can trigger a run for a task that has not been deployed yet. The run enters a Pending version state and starts executing once the task is deployed. This is useful in CI/CD pipelines where you want to enqueue work before the deployment completes.

Real-time run updates

Subscribe to a run’s state changes in real time:
import { runs } from "@trigger.dev/sdk";
import type { myTask } from "./trigger/myTask";

for await (const run of runs.subscribeToRun<typeof myTask>("run_1234")) {
  console.log(run.status);

  if (run.isCompleted) {
    console.log("Output:", run.output);
    break;
  }
}
For more on real-time updates, see the Realtime documentation.

Build docs developers (and LLMs) love