コンテンツにスキップ

Temporal Cheat Sheet

Overview

Temporal is an open-source durable execution platform that enables developers to build reliable distributed applications without worrying about infrastructure complexity. Workflows in Temporal are fault-tolerant by design — they survive process crashes, server outages, and network failures, automatically resuming exactly where they left off.

Temporal separates workflow logic (orchestration) from activities (side effects like API calls or database writes). The Temporal server maintains the complete event history of each workflow execution, enabling replay-based recovery. It supports multiple programming languages including Go, Java, TypeScript, Python, and .NET through official SDKs.

Installation

Temporal CLI (Development Server)

# macOS
brew install temporal

# Linux / Other
curl -sSf https://temporal.download/cli.sh | sh

# Start development server
temporal server start-dev

# With custom port and namespace
temporal server start-dev --port 7233 --ui-port 8233 --namespace my-namespace

# Web UI available at http://localhost:8233

Docker Compose

version: '3.5'
services:
  temporal:
    image: temporalio/auto-setup:latest
    ports:
      - "7233:7233"
    environment:
      - DB=postgresql
      - DB_PORT=5432
      - POSTGRES_USER=temporal
      - POSTGRES_PWD=temporal
      - POSTGRES_SEEDS=postgresql
  temporal-ui:
    image: temporalio/ui:latest
    ports:
      - "8080:8080"
    environment:
      - TEMPORAL_ADDRESS=temporal:7233
  postgresql:
    image: postgres:15
    environment:
      POSTGRES_USER: temporal
      POSTGRES_PASSWORD: temporal

SDK Installation

# Go
go get go.temporal.io/sdk

# TypeScript
npm install @temporalio/client @temporalio/worker @temporalio/workflow @temporalio/activity

# Python
pip install temporalio

# Java (Maven)
# <dependency>
#   <groupId>io.temporal</groupId>
#   <artifactId>temporal-sdk</artifactId>
#   <version>1.24.0</version>
# </dependency>

Core Concepts

ConceptDescription
WorkflowDurable function that orchestrates activities
ActivityNon-deterministic operation (I/O, API calls)
Task QueueNamed queue connecting workflows/activities to workers
WorkerProcess that polls task queues and executes code
SignalAsync message sent to a running workflow
QuerySynchronous read of workflow state
ScheduleCron-like recurring workflow execution

Workflow Definition (TypeScript)

// workflows.ts
import { proxyActivities, sleep, defineSignal, defineQuery,
         setHandler, condition } from '@temporalio/workflow';
import type * as activities from './activities';

const { sendEmail, processPayment, updateInventory } = proxyActivities<
  typeof activities
>({
  startToCloseTimeout: '30s',
  retry: {
    maximumAttempts: 3,
    initialInterval: '1s',
    backoffCoefficient: 2,
  },
});

export const cancelOrder = defineSignal('cancelOrder');
export const getStatus = defineQuery<string>('getStatus');

export async function orderWorkflow(orderId: string, items: string[]) {
  let status = 'processing';
  let cancelled = false;

  setHandler(cancelOrder, () => { cancelled = true; });
  setHandler(getStatus, () => status);

  status = 'payment';
  await processPayment(orderId);

  if (cancelled) {
    status = 'cancelled';
    return { status: 'cancelled' };
  }

  status = 'fulfillment';
  await updateInventory(items);

  status = 'notification';
  await sendEmail(orderId, 'Your order is confirmed!');

  // Wait 24 hours then follow up
  await sleep('24h');
  await sendEmail(orderId, 'How was your experience?');

  status = 'completed';
  return { status: 'completed', orderId };
}

Activity Definition

// activities.ts
export async function sendEmail(orderId: string, message: string) {
  const response = await fetch('https://api.email.com/send', {
    method: 'POST',
    body: JSON.stringify({ orderId, message }),
  });
  return response.json();
}

export async function processPayment(orderId: string) {
  // Call payment API
  return { success: true, transactionId: 'txn_123' };
}

export async function updateInventory(items: string[]) {
  // Update inventory system
  return { updated: items.length };
}

Worker Setup

// 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: 'order-processing',
    maxConcurrentActivityTaskExecutions: 100,
    maxConcurrentWorkflowTaskExecutions: 50,
  });

  await worker.run();
}

run().catch(console.error);

Client Usage

// client.ts
import { Client } from '@temporalio/client';

const client = new Client();

// Start a workflow
const handle = await client.workflow.start('orderWorkflow', {
  taskQueue: 'order-processing',
  workflowId: `order-${orderId}`,
  args: [orderId, ['item1', 'item2']],
  workflowRunTimeout: '24h',
});

// Get result
const result = await handle.result();

// Query workflow state
const status = await handle.query('getStatus');

// Send signal
await handle.signal('cancelOrder');

// Cancel workflow
await handle.cancel();

// Terminate workflow
await handle.terminate('Terminated by admin');

CLI Commands

CommandDescription
temporal workflow start --task-queue q --type wfStart a workflow
temporal workflow show -w <workflow-id>Show workflow details
temporal workflow listList workflows
temporal workflow signal -w <id> --name sigSignal a workflow
temporal workflow query -w <id> --name qQuery workflow state
temporal workflow cancel -w <id>Cancel a workflow
temporal workflow terminate -w <id>Terminate a workflow
temporal task-queue describe -t <queue>Describe task queue
temporal schedule create --schedule-id s1Create a schedule
temporal schedule listList schedules

Configuration

Worker Tuning

const worker = await Worker.create({
  taskQueue: 'main',
  workflowsPath: require.resolve('./workflows'),
  activities,
  maxConcurrentActivityTaskExecutions: 200,
  maxConcurrentWorkflowTaskExecutions: 100,
  maxCachedWorkflows: 600,
  stickyQueueScheduleToStartTimeout: '10s',
  reuseV8Context: true,
});

Retry Policies

const activities = proxyActivities({
  startToCloseTimeout: '1m',
  retry: {
    initialInterval: '1s',
    backoffCoefficient: 2.0,
    maximumInterval: '1m',
    maximumAttempts: 5,
    nonRetryableErrorTypes: ['InvalidInputError'],
  },
});

Advanced Usage

Schedules (Cron Workflows)

temporal schedule create \
  --schedule-id daily-report \
  --workflow-type generateReport \
  --task-queue reports \
  --cron '0 8 * * *'

Child Workflows

import { executeChild } from '@temporalio/workflow';

export async function parentWorkflow(items: string[]) {
  const results = await Promise.all(
    items.map((item) =>
      executeChild('processItem', {
        args: [item],
        taskQueue: 'items',
      })
    )
  );
  return results;
}

Saga Pattern (Compensation)

export async function sagaWorkflow(orderId: string) {
  const compensations: Array<() => Promise<void>> = [];

  try {
    await reserveInventory(orderId);
    compensations.push(() => releaseInventory(orderId));

    await processPayment(orderId);
    compensations.push(() => refundPayment(orderId));

    await shipOrder(orderId);
  } catch (err) {
    // Run compensations in reverse
    for (const compensate of compensations.reverse()) {
      await compensate();
    }
    throw err;
  }
}

Troubleshooting

IssueSolution
Workflow stuckCheck worker is running on the correct task queue; inspect event history
Non-determinism errorWorkflow code must be deterministic; avoid random, Date.now(), or side effects
Activity timeoutIncrease startToCloseTimeout; check activity is completing properly
Worker not picking up tasksVerify task queue name matches between client and worker
History too largeBreak into child workflows; reduce number of events per workflow
Schedule not triggeringVerify schedule is running (temporal schedule describe); check cron expression
Connection refusedEnsure Temporal server is running on the expected address and port
Workflow already runningUse workflowIdReusePolicy to control behavior on duplicate IDs