Temporal
Integrate Temporal workflow engine for durable execution of long-running
You are a workflow orchestration architect who integrates Temporal for durable execution. Temporal is an open-source platform that guarantees workflow completion even through failures, restarts, and deployments. You design workflows as deterministic state machines with activities for side effects, signals for external input, and queries for real-time state inspection. ## Key Points - **Non-deterministic workflow code**: Using `Date.now()`, `Math.random()`, or `fetch` in workflows breaks replay; use Temporal APIs instead. - **Missing activity timeouts**: Without `startToCloseTimeout`, a stuck activity retries indefinitely, consuming resources forever. - **Mutating state in query handlers**: Queries must be read-only; mutations cause non-determinism during replay. - **Overly large workflow histories**: Workflows with millions of events slow down; use `continueAsNew` for long-running loops. - Long-running business processes spanning hours or days (order fulfillment, onboarding) - Workflows requiring human approval steps with durable wait states - Saga patterns coordinating distributed transactions across services - Scheduled recurring tasks with visibility into execution state and history - Mission-critical pipelines where failure recovery must be guaranteed ## Quick Example ```bash npm install @temporalio/client @temporalio/worker @temporalio/workflow @temporalio/activity ``` ```env TEMPORAL_ADDRESS=localhost:7233 TEMPORAL_NAMESPACE=default TEMPORAL_TASK_QUEUE=main-queue TEMPORAL_TLS_CERT_PATH= TEMPORAL_TLS_KEY_PATH= ```
skilldb get queue-workflow-services-skills/TemporalFull skill: 202 linesTemporal Integration
You are a workflow orchestration architect who integrates Temporal for durable execution. Temporal is an open-source platform that guarantees workflow completion even through failures, restarts, and deployments. You design workflows as deterministic state machines with activities for side effects, signals for external input, and queries for real-time state inspection.
Core Philosophy
Deterministic Workflow Code
Workflow functions must be completely deterministic because Temporal replays them from the event history to reconstruct state. Never use Date.now(), Math.random(), network calls, or file I/O directly in workflow code. Use Temporal's built-in APIs: workflow.now() for time, workflow.sleep() for delays, and activities for all non-deterministic operations.
Any change to workflow logic that alters the sequence of recorded events breaks replay compatibility. Use versioning (workflow.patched()) to introduce changes safely in running workflows. Never rename or reorder activity calls without a version guard.
Activity Isolation
Activities perform the actual work: API calls, database writes, file operations. They run outside the workflow sandbox and can fail, timeout, and retry independently. Configure retry policies per activity based on failure characteristics: exponential backoff for transient errors, no retry for validation errors.
Set explicit timeouts for every activity. scheduleToCloseTimeout bounds total time including retries. startToCloseTimeout bounds each individual attempt. heartbeatTimeout detects stuck activities. Without timeouts, a failing activity retries forever.
Signal and Query Design
Signals deliver asynchronous events to running workflows without blocking the sender. Use signals for human approvals, external webhook events, and cross-workflow communication. Design signal handlers to be idempotent because signals can be delivered more than once during replay.
Queries read workflow state synchronously without modifying it. Never mutate workflow state in a query handler. Use queries for dashboards, status checks, and administrative inspection.
Setup
Install
npm install @temporalio/client @temporalio/worker @temporalio/workflow @temporalio/activity
Environment Variables
TEMPORAL_ADDRESS=localhost:7233
TEMPORAL_NAMESPACE=default
TEMPORAL_TASK_QUEUE=main-queue
TEMPORAL_TLS_CERT_PATH=
TEMPORAL_TLS_KEY_PATH=
Key Patterns
1. Workflow Definition
Do:
import { proxyActivities, sleep, defineSignal, setHandler, condition } from "@temporalio/workflow";
import type * as activities from "./activities";
const { processPayment, sendConfirmation, refundPayment } = proxyActivities<typeof activities>({
startToCloseTimeout: "30s",
retry: { maximumAttempts: 3, backoffCoefficient: 2 },
});
export const approvalSignal = defineSignal<[boolean]>("approval");
export async function orderWorkflow(orderId: string, amount: number): Promise<string> {
let approved: boolean | undefined;
setHandler(approvalSignal, (result) => { approved = result; });
const paymentId = await processPayment(orderId, amount);
const gotApproval = await condition(() => approved !== undefined, "24h");
if (!gotApproval || !approved) {
await refundPayment(paymentId);
return "cancelled";
}
await sendConfirmation(orderId);
return "completed";
}
Not this:
// Non-deterministic: uses Date, fetch, no timeouts
export async function orderWorkflow(orderId: string) {
const now = new Date(); // BREAKS REPLAY
const resp = await fetch("/api/payment"); // SIDE EFFECT IN WORKFLOW
await new Promise(r => setTimeout(r, 5000)); // USE workflow.sleep()
}
2. Activity Implementation
Do:
import { heartbeat, Context } from "@temporalio/activity";
export async function processPayment(orderId: string, amount: number): Promise<string> {
const result = await paymentGateway.charge(orderId, amount);
return result.transactionId;
}
export async function processLargeFile(fileUrl: string): Promise<void> {
const chunks = await downloadChunks(fileUrl);
for (let i = 0; i < chunks.length; i++) {
await processChunk(chunks[i]);
heartbeat({ progress: (i + 1) / chunks.length }); // report progress
}
}
Not this:
// No heartbeat for long activity, no error context
export async function processLargeFile(fileUrl: string) {
const data = await fetch(fileUrl);
await processEntireFile(data); // could run for hours with no heartbeat
}
3. Worker Setup
Do:
import { Worker } from "@temporalio/worker";
const worker = await Worker.create({
workflowsPath: require.resolve("./workflows"),
activities: require("./activities"),
taskQueue: process.env.TEMPORAL_TASK_QUEUE!,
maxConcurrentActivityTaskExecutions: 20,
maxConcurrentWorkflowTaskExecutions: 40,
});
await worker.run();
Not this:
// No concurrency limits, inline activities
const worker = await Worker.create({
workflowsPath: require.resolve("./workflows"),
taskQueue: "default",
});
Common Patterns
Starting a Workflow from a Client
import { Client, Connection } from "@temporalio/client";
const connection = await Connection.connect({ address: process.env.TEMPORAL_ADDRESS });
const client = new Client({ connection, namespace: process.env.TEMPORAL_NAMESPACE });
const handle = await client.workflow.start(orderWorkflow, {
taskQueue: process.env.TEMPORAL_TASK_QUEUE!,
workflowId: `order-${orderId}`,
args: [orderId, amount],
workflowExecutionTimeout: "7d",
});
// Send signal
await handle.signal(approvalSignal, true);
// Query state
const result = await handle.result();
Workflow Versioning
import { patched } from "@temporalio/workflow";
export async function orderWorkflow(orderId: string): Promise<string> {
if (patched("v2-add-fraud-check")) {
await fraudCheck(orderId); // new step added safely
}
await processPayment(orderId);
return "done";
}
Child Workflows
import { executeChild } from "@temporalio/workflow";
export async function batchWorkflow(orderIds: string[]): Promise<void> {
await Promise.all(
orderIds.map((id) =>
executeChild(orderWorkflow, {
workflowId: `order-${id}`,
args: [id, 0],
})
)
);
}
Anti-Patterns
- Non-deterministic workflow code: Using
Date.now(),Math.random(), orfetchin workflows breaks replay; use Temporal APIs instead. - Missing activity timeouts: Without
startToCloseTimeout, a stuck activity retries indefinitely, consuming resources forever. - Mutating state in query handlers: Queries must be read-only; mutations cause non-determinism during replay.
- Overly large workflow histories: Workflows with millions of events slow down; use
continueAsNewfor long-running loops.
When to Use
- Long-running business processes spanning hours or days (order fulfillment, onboarding)
- Workflows requiring human approval steps with durable wait states
- Saga patterns coordinating distributed transactions across services
- Scheduled recurring tasks with visibility into execution state and history
- Mission-critical pipelines where failure recovery must be guaranteed
Install this skill directly: skilldb add queue-workflow-services-skills
Related Skills
AWS Sqs
Integrate AWS SQS for scalable message queuing with FIFO ordering, dead-letter
Celery
Integrate Celery distributed task queue for Python-based async job processing
Inngest
Integrate Inngest event-driven functions for durable step execution with
Kafka
Integrate Apache Kafka event streaming using KafkaJS for high-throughput
Pgboss
Integrate pg-boss for PostgreSQL-backed job queuing with delayed jobs, retry
Rabbitmq
Integrate RabbitMQ message broker using amqplib for reliable async messaging.