Agent Wranglers

STK-105Default Open source

Use Temporal for long workflows that must survive restarts

Run a business process that spans several steps, services or days as a Temporal workflow, not as a hand-made chain of queues and status columns. An order from payment to delivery is one example.

Review by

2027-04-30

How to do it

Temporal passes the five tests. The server reached 1.0.0 on 30 September 2020, and 1.32.1 shipped on 8 October 2026. Its Python SDK temporalio had about 10.5 million weekly PyPI downloads in October 2026, and its GitHub repository about 24,000 stars. A workflow is plain code. Temporal records each step, so after a crash or deploy the workflow resumes where it stopped. Retries, timers of days and compensation steps then need no code of your own. Each step that calls another system is an activity and must be safe to repeat, as Make writes safe to repeat says. Self-hosting needs a database, such as PostgreSQL. Choose something else when each job is short and stands alone. Then Use BullMQ or RQ for background jobs is simpler.

Examples

Python example

from datetime import timedelta
from temporalio import workflow

with workflow.unsafe.imports_passed_through():
    from shop.activities import charge_card, book_courier, refund_card

@workflow.defn
class FulfilOrder:
    @workflow.run
    async def run(self, order_id: str) -> str:
        await workflow.execute_activity(charge_card, order_id, start_to_close_timeout=timedelta(minutes=1))
        try:
            return await workflow.execute_activity(book_courier, order_id, start_to_close_timeout=timedelta(hours=1))
        except Exception:
            await workflow.execute_activity(refund_card, order_id, start_to_close_timeout=timedelta(minutes=1))
            raise

TypeScript example

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

const { chargeCard, bookCourier, refundCard } = proxyActivities<typeof activities>({ startToCloseTimeout: '1 minute' });

export async function fulfilOrder(orderId: string): Promise<string> {
  await chargeCard(orderId);
  try {
    return await bookCourier(orderId);
  } catch (error) {
    await refundCard(orderId);
    throw error;
  }
}

How to check

Every process with more than two steps across services has a workflow definition in the repository. A test kills the worker in the middle of a workflow, starts it again, and the workflow finishes with each activity applied once.

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/stack/databases-and-storage/durable-workflows">Agent Wranglers software choices playbook</a>. In code you write, add a comment next to it with the same link.