Temporal.io: Workflow Orchestration That Survives Restarts
Why I run Temporal on my homelab — and how durable workflow execution changes the way you think about long-running background jobs.
Cron jobs and message queues solve most scheduling problems, but they share a common failure mode: if the process crashes mid-execution, the state is gone. You either re-run the whole job (and handle idempotency) or accept partial work. Temporal solves this by making workflow state durable — a workflow that crashes mid-step resumes from exactly where it left off after a restart.
The core idea
A Temporal workflow is just code — a function in any supported language (Go, TypeScript, Python, Java, .NET). But instead of running in memory, every state transition is written to a durable event log. If the worker process dies, a new worker picks up the workflow, replays the event log to restore state, and continues from the last committed step. Your code sees none of this — it looks like the function never stopped.
// A workflow that survives restarts mid-execution
import { proxyActivities, sleep } from "@temporalio/workflow";
const { sendEmail, processPayment, updateInventory } = proxyActivities({
startToCloseTimeout: "5 minutes",
});
export async function orderWorkflow(orderId: string) {
await processPayment(orderId); // if worker dies here...
await sleep("10 seconds");
await updateInventory(orderId); // ...it resumes here after restart
await sendEmail(orderId, "confirmed");
}When you actually need this
- ▸Multi-step processes that span minutes or hours (order fulfillment, data pipelines)
- ▸Human-in-the-loop flows that wait for approval before continuing
- ▸Retry logic with complex backoff that you don't want to implement yourself
- ▸Workflows that call external APIs and need to handle partial failures gracefully
- ▸Replacing fragile cron + database flag patterns
Self-hosting with Docker
Temporal's self-hosted stack is: the Temporal server, a PostgreSQL database for workflow state, Elasticsearch for visibility/search, and the admin-tools container for CLI access. The auto-setup image handles schema migration on first start. Workers are separate services you write — they poll Temporal for tasks and execute your workflow and activity code.
# Check namespace list
docker exec temporal-admin-tools tctl namespace list
# List running workflows
docker exec temporal-admin-tools tctl workflow list
# Describe a specific workflow
docker exec temporal-admin-tools tctl workflow describe --workflow_id your-idWhat it replaces in practice
I've replaced several cron + bash script patterns with Temporal workflows: nightly backup verification that chains multiple steps, a media sync workflow that retries on network failures, and an alert escalation flow that waits for acknowledgment before notifying the next person. The visibility UI alone (seeing exactly which step a workflow is on, its history, input/output per step) pays for the operational overhead of running the stack.