mech.app
Automation

Trigger.dev V2: TypeScript Workflow Engine with Durable Execution

How Trigger.dev implements durable execution, state persistence, and resumable functions in TypeScript without Temporal's Go runtime or complex deployment.

Source: trigger.dev
Trigger.dev V2: TypeScript Workflow Engine with Durable Execution

Trigger.dev V2 pivoted from a Zapier-style automation platform to a durable execution engine for TypeScript. The shift addresses a specific gap: developers building long-running workflows (AI agents, media pipelines, data orchestration) want Temporal’s reliability without learning Go or operating a distributed system.

The V2 architecture exposes workflow orchestration primitives directly in TypeScript, handling state persistence, retries, and resumable functions through a managed runtime. This matters for agentic systems where a single workflow might call multiple LLMs, wait for human approval, process files, and run for hours or days.

What Durable Execution Solves

Standard serverless functions timeout after 15 minutes (AWS Lambda) or 60 minutes (Vercel). Long-running workflows require:

  • State persistence across function invocations
  • Automatic retries with exponential backoff
  • Resumability after code deploys or infrastructure failures
  • Observability into multi-step execution graphs

Temporal solves this with a separate workflow engine written in Go, requiring developers to learn workflow DSL semantics and operate worker pools. Trigger.dev embeds the orchestration layer into a TypeScript runtime, trading some of Temporal’s distributed systems flexibility for faster onboarding.

Architecture: How State Persists

Trigger.dev tasks are TypeScript functions wrapped in a task() primitive:

export const researchAgent = task({
  id: "research-agent",
  run: async ({ topic }: { topic: string }) => {
    const messages: CoreMessage[] = [
      { role: "user", content: `Research: ${topic}` }
    ];
    
    for (let i = 0; i < 10; i++) {
      const { text, toolCalls, steps } = await generateText({
        model: anthropic("claude-opus-4-20250514"),
        system: "You are a research assistant with web access.",
        messages,
        tools: { search, browse, analyze },
        maxSteps: 5,
      });
      
      if (!toolCalls.length) {
        return { summary: text, stepsUsed: steps.length };
      }
      
      for (const call of toolCalls) {
        const result = await executeTool(call);
        messages.push({ 
          role: "tool", 
          content: JSON.stringify(result) 
        });
      }
    }
    
    return { summary: "Max iterations reached", stepsUsed: 10 };
  }
});

Under the hood, the runtime:

  1. Checkpoints state after each await boundary
  2. Persists execution context to Postgres or managed storage
  3. Replays from last checkpoint on retry or resume
  4. Tracks tool calls and external API responses for idempotency

The key difference from Temporal: no separate workflow definition language. The TypeScript code is the workflow. The runtime instruments async boundaries to create resumption points.

State Management Trade-offs

FeatureTrigger.dev V2Temporal
State storageManaged Postgres or self-hosted DBCassandra, PostgreSQL, MySQL (self-managed)
Replay semanticsAutomatic at await boundariesDeterministic replay from event log
Code versioningTask ID + version tagsWorkflow versioning with compatibility checks
Failure recoveryAutomatic retry with exponential backoffConfigurable retry policies per activity
ObservabilityBuilt-in tracing UIRequires Temporal Web + custom instrumentation
DeploymentManaged runtime or Docker containerWorker pools + Temporal server cluster

Trigger.dev’s approach works well for teams that want to ship workflows fast. The automatic checkpointing reduces repetitive setup code but hides some control. Temporal gives you fine-grained activity boundaries and explicit compensation logic, which matters for financial transactions or multi-tenant systems with strict isolation requirements.

Resumable Functions: Implementation Details

When a task pauses (waiting for an LLM response, a webhook callback, or a scheduled delay), Trigger.dev:

  1. Serializes the execution state (local variables, message arrays, loop counters)
  2. Stores it in the task run record
  3. Releases the worker process
  4. Resumes from the exact line when the event arrives

This is similar to how Durable Functions (Azure) or Step Functions (AWS) work, but without cloud-specific APIs or proprietary SDKs. The managed runtime uses V8 isolates for lightweight task isolation, while self-hosted deployments run tasks in containerized workers for stronger security boundaries.

Common failure modes:

  • Non-deterministic code (random number generation, Date.now()) breaks replay. Trigger.dev provides ctx.random() and ctx.now() helpers.
  • Large state objects (multi-MB message arrays) slow serialization. Consider pagination or external storage.
  • External API changes during a long-running task can cause schema mismatches. Version your tool call interfaces.

Deployment Shapes

Trigger.dev offers three deployment options:

  1. Managed cloud: Tasks run on Trigger.dev infrastructure. You push code, they handle scaling and persistence.
  2. Self-hosted (Docker): Run the runtime and dashboard in your VPC. Requires Postgres and Redis.
  3. Hybrid: Use managed orchestration with self-hosted workers for sensitive workloads.

For agentic AI projects, the managed option reduces operational overhead. For regulated industries (healthcare, finance), self-hosted gives you data residency and audit trails.

Observability and Debugging

The Trigger.dev dashboard shows:

  • Real-time task execution graphs
  • Step-by-step tool call traces
  • Retry attempts and failure reasons
  • Concurrency and queue depth metrics

Unlike Temporal’s workflow history (which stores execution events as serialized protobuf messages requiring custom tooling to parse), Trigger.dev surfaces execution state in a developer-friendly UI. You can inspect message arrays, see which LLM calls succeeded, and replay failed steps from the browser.

Limitation: The tracing model assumes tasks complete within days, not months. For workflows that span weeks (compliance reviews, multi-stage approvals), you’ll need external state management or a hybrid approach with Temporal.

Security Boundaries

Trigger.dev tasks run in isolated environments (V8 isolates or containers). Key security considerations:

  • Secrets management: Use environment variables or integrate with Vault/AWS Secrets Manager. Secrets are not logged or persisted in task state.
  • Network isolation: Self-hosted deployments can restrict outbound traffic. Managed mode allows VPC peering.
  • Code signing: Task deployments can require signed commits (enterprise feature).
  • Audit logs: All task invocations, retries, and state changes are logged with timestamps and user context.

For multi-tenant AI agents, isolate tasks by tenant ID and use separate API keys per customer. Trigger.dev does not enforce tenant boundaries at the runtime level.

When to Use Trigger.dev vs. Temporal

Choose Trigger.dev if:

  • Your team writes TypeScript and wants to avoid Go
  • You need workflows running in hours or days, not weeks
  • You want managed infrastructure with minimal ops overhead
  • Your workflows are primarily API orchestration (LLM calls, webhooks, file processing)

Choose Temporal if:

  • You need multi-language support (Go, Java, Python workers)
  • Your workflows require strict transactional semantics (saga patterns, compensation)
  • You operate at scale where custom worker pools and sharding matter
  • You need workflow executions spanning months with complex versioning

Avoid both if:

  • Your tasks complete in seconds (use queues like BullMQ or SQS)
  • You need real-time streaming (use Kafka or event-driven architectures)
  • Your workflows are simple CRUD operations (use database triggers or cron jobs)

Technical Verdict

Trigger.dev V2 delivers durable execution for TypeScript developers who don’t want to operate Temporal. The automatic checkpointing and resumable functions reduce repetitive setup overhead, making it faster to ship AI agents and multi-step workflows. The managed runtime handles scaling and observability without requiring distributed systems expertise.

The trade-off: less control over replay semantics and activity boundaries. For financial systems or workflows requiring explicit compensation logic, Temporal’s primitives are more robust. For most AI orchestration (agent loops, media pipelines, data enrichment), Trigger.dev’s developer experience is superior.

Use it when you want to focus on workflow logic, not infrastructure. Avoid it when you need fine-grained control over execution guarantees or multi-month workflow lifetimes.