home / skills / willsigmon / sigstack / temporal-expert

This skill helps you design durable Temporal workflows that survive failures, with automatic retries, versioning, and complete visibility.

npx playbooks add skill willsigmon/sigstack --skill temporal-expert

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
4.2 KB
---
name: Temporal Expert
description: Temporal - durable workflows, long-running processes, reliable execution
allowed-tools: Read, Edit, Bash, WebFetch
model: sonnet
---

# Temporal Expert

Build bulletproof workflows that survive failures.

## What is Temporal?

Durable execution platform for long-running, reliable workflows.

- **Survives crashes**: Workflow resumes exactly where it left off
- **Automatic retries**: Failed activities retry with backoff
- **Versioning**: Update workflows without breaking running ones
- **Visibility**: Full history of every execution

## When to Use Temporal

### Good Fit
- Multi-step order processing
- Payment workflows
- Data pipelines
- Long-running background jobs
- Saga patterns (distributed transactions)

### Overkill For
- Simple CRUD
- Single API calls
- Fast synchronous operations

## Pricing (2026)

- **Self-hosted**: Free (complex to operate)
- **Temporal Cloud**: $25/mo base + $0.035/action

## Quick Start (TypeScript)

### Install
```bash
npm install @temporalio/client @temporalio/worker @temporalio/workflow @temporalio/activity
```

### Define Workflow
```typescript
// workflows.ts
import { proxyActivities } from '@temporalio/workflow';
import type * as activities from './activities';

const { sendEmail, chargeCard, shipOrder } = proxyActivities<typeof activities>({
  startToCloseTimeout: '5 minutes',
  retry: {
    maximumAttempts: 3,
  },
});

export async function orderWorkflow(orderId: string): Promise<void> {
  // Each step is durable - survives crashes
  await chargeCard(orderId);
  await shipOrder(orderId);
  await sendEmail(orderId, 'Your order has shipped!');
}
```

### Define Activities
```typescript
// activities.ts
export async function chargeCard(orderId: string): Promise<void> {
  // Call payment API
}

export async function shipOrder(orderId: string): Promise<void> {
  // Call shipping API
}

export async function sendEmail(orderId: string, message: string): Promise<void> {
  // Send email
}
```

### Start Worker
```typescript
// worker.ts
import { Worker } from '@temporalio/worker';
import * as activities from './activities';

async function run() {
  const worker = await Worker.create({
    workflowsPath: require.resolve('./workflows'),
    activities,
    taskQueue: 'orders',
  });
  await worker.run();
}
```

### Execute Workflow
```typescript
// client.ts
import { Client } from '@temporalio/client';
import { orderWorkflow } from './workflows';

const client = new Client();

await client.workflow.start(orderWorkflow, {
  taskQueue: 'orders',
  workflowId: `order-${orderId}`,
  args: [orderId],
});
```

## Saga Pattern

Handle distributed rollbacks:

```typescript
export async function bookingWorkflow(booking: Booking): Promise<void> {
  try {
    await reserveFlight(booking.flightId);
    await reserveHotel(booking.hotelId);
    await chargePayment(booking.paymentId);
  } catch (error) {
    // Compensating transactions
    await cancelFlight(booking.flightId);
    await cancelHotel(booking.hotelId);
    throw error;
  }
}
```

## Docker Compose Setup

```yaml
version: '3.8'
services:
  temporal:
    image: temporalio/auto-setup:1.22
    ports:
      - "7233:7233"
    environment:
      - DB=postgresql
      - DB_PORT=5432
      - POSTGRES_USER=temporal
      - POSTGRES_PWD=temporal
      - POSTGRES_SEEDS=postgresql

  temporal-ui:
    image: temporalio/ui:2.21
    ports:
      - "8080:8080"
    environment:
      - TEMPORAL_ADDRESS=temporal:7233
```

## Best Practices

### 1. Idempotent Activities
```typescript
export async function chargeCard(orderId: string): Promise<void> {
  // Check if already charged
  const existing = await getPayment(orderId);
  if (existing) return;

  await processPayment(orderId);
}
```

### 2. Use Workflow IDs
```typescript
// Prevents duplicate workflows
await client.workflow.start(orderWorkflow, {
  workflowId: `order-${orderId}`,  // Same ID = same workflow
});
```

### 3. Heartbeats for Long Activities
```typescript
export async function processLargeFile(fileId: string): Promise<void> {
  for (const chunk of chunks) {
    await processChunk(chunk);
    Context.current().heartbeat();  // Keep alive
  }
}
```

Use when: Multi-step workflows, payment processing, data pipelines, reliability needed

Overview

This skill helps you design and run durable, long-running workflows using Temporal. I provide clear patterns, TypeScript examples, and operational tips to build fault-tolerant processes that survive crashes and automatic retries. The focus is on practical setup, common workflow patterns, and production best practices.

How this skill works

I show how to define workflows and activities in TypeScript, run workers, and start executions from a client. Workflows are durable state machines with full execution history; activities are the external tasks that can be retried and made idempotent. I also cover deployment basics such as Docker Compose and Temporal Cloud vs self-hosted tradeoffs.

When to use it

  • Multi-step order processing across services where progress must be durable
  • Payment workflows and other financial flows needing retries and visibility
  • Long-running background jobs and data pipelines that may span hours or days
  • Saga-style distributed transactions that require compensating actions
  • When you need automatic retries, versioning, and execution history for debugging

Best practices

  • Make activities idempotent: check previous state before performing external side effects
  • Use stable workflowId values to prevent accidental duplicate executions
  • Emit heartbeats from long-running activities to signal liveness and allow retries
  • Keep workflows deterministic: avoid non-deterministic logic in workflow code
  • Use retries and backoff policies for transient failures and compensating actions for irreversible steps

Example use cases

  • Order fulfillment: charge card, ship items, notify customer with automatic resume on failure
  • Booking systems: reserve resources and run compensating cancellations on failure (Saga)
  • ETL pipelines: durable multi-step data processing that can resume after crashes
  • Subscription billing: scheduled, retryable billing attempts with audit history
  • Large file processing: chunked processing with heartbeats and checkpointing

FAQ

Is Temporal overkill for simple APIs or CRUD?

Yes. Temporal excels for multi-step, long-running or failure-prone workflows. For simple synchronous calls or basic CRUD, a lightweight approach is preferable.

What about cost and hosting?

Self-hosting is free but operationally complex. Temporal Cloud offers managed hosting with a base fee plus per-action pricing—choose based on team ops capacity and scale.