DEV Community

Alex Spinov
Alex Spinov

Posted on

Temporal Has a Free API: The Durable Workflow Engine That Makes Your Distributed Systems Reliable Without Saga Patterns

Your order processing pipeline has 7 steps. Step 5 fails because a third-party API is down. Now you need retry logic, compensation logic for steps 1-4, a dead letter queue, and state tracking. You've just invented a worse version of Temporal.

What Temporal Actually Does

Temporal is an open-source durable execution platform. You write workflows as normal code (if/else, loops, function calls), and Temporal guarantees they complete — even if servers crash, networks fail, or processes restart. Every line of your workflow code is automatically persisted, so execution resumes exactly where it left off.

Temporal replaces message queues, cron jobs, saga patterns, and state machines with a single primitive: durable functions. Your workflow code looks like a regular function but is resilient to any infrastructure failure.

SDKs for Go, Java, Python, TypeScript, PHP, .NET, Ruby. Self-hosted (free, open-source) or Temporal Cloud (free tier: 1000 actions/month). The self-hosted version is the same code that runs Temporal Cloud.

Quick Start

Self-hosted:

temporal server start-dev
Enter fullscreen mode Exit fullscreen mode

TypeScript SDK:

npm install @temporalio/client @temporalio/worker @temporalio/workflow @temporalio/activity
Enter fullscreen mode Exit fullscreen mode

Define activities (the actual work):

// activities.ts
export async function chargePayment(orderId: string, amount: number): Promise<string> {
  const response = await stripe.charges.create({ amount, currency: 'usd' });
  return response.id;
}

export async function sendConfirmation(email: string, orderId: string): Promise<void> {
  await emailService.send({ to: email, template: 'order-confirmed', data: { orderId } });
}

export async function reserveInventory(items: Item[]): Promise<string> {
  return await inventoryService.reserve(items);
}
Enter fullscreen mode Exit fullscreen mode

Define workflow (the orchestration):

// workflows.ts
import { proxyActivities } from '@temporalio/workflow';
import type * as activities from './activities';

const { chargePayment, sendConfirmation, reserveInventory } = 
  proxyActivities<typeof activities>({
    startToCloseTimeout: '30s',
    retry: { maximumAttempts: 5 }
  });

export async function orderWorkflow(order: Order): Promise<string> {
  // Step 1: Reserve inventory
  const reservationId = await reserveInventory(order.items);

  // Step 2: Charge payment
  const paymentId = await chargePayment(order.id, order.total);

  // Step 3: Send confirmation
  await sendConfirmation(order.email, order.id);

  return paymentId;
  // If any step fails, Temporal retries automatically
  // If the server crashes mid-workflow, it resumes from the last completed step
}
Enter fullscreen mode Exit fullscreen mode

Start a workflow:

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

const client = new Client();
const result = await client.workflow.start(orderWorkflow, {
  taskQueue: 'orders',
  workflowId: `order-${orderId}`,
  args: [order]
});
Enter fullscreen mode Exit fullscreen mode

3 Practical Use Cases

1. Long-Running Business Processes

export async function subscriptionWorkflow(customerId: string) {
  while (true) {
    await chargeMonthly(customerId);
    await sleep('30 days'); // Temporal handles this — even across server restarts

    const status = await checkSubscriptionStatus(customerId);
    if (status === 'cancelled') break;
  }
  await sendCancellationEmail(customerId);
}
Enter fullscreen mode Exit fullscreen mode

A subscription that runs for years, surviving any number of deployments and restarts.

2. Human-in-the-Loop Approval

export async function expenseApproval(expense: Expense) {
  await notifyManager(expense);

  // Wait up to 7 days for manager approval
  const approved = await condition(
    () => approvalReceived,
    '7 days'
  );

  if (approved) {
    await processReimbursement(expense);
  } else {
    await notifyRejection(expense);
  }
}
Enter fullscreen mode Exit fullscreen mode

3. Reliable Data Pipeline

export async function etlPipeline(source: string) {
  const rawData = await extractData(source);
  const transformed = await transformData(rawData);
  await loadData(transformed);
  await validateData(transformed.id);
  await notifyStakeholders(transformed.summary);
}
Enter fullscreen mode Exit fullscreen mode

Every step retries on failure. State is persisted. No data loss.

Why This Matters

Temporal eliminates an entire class of infrastructure complexity. Instead of stitching together queues, state machines, cron jobs, and retry logic, you write normal code and Temporal handles durability. For any system with multi-step processes, external API calls, or long-running operations, Temporal is the most impactful infrastructure investment you can make.


Need custom data extraction or web scraping solutions? I build production-grade scrapers and data pipelines. Check out my Apify actors or email me at spinov001@gmail.com for custom projects.

Follow me for more free API discoveries every week!

Top comments (0)