Introduction
Temporal solves the hardest problem in distributed systems: reliability. When your business process spans multiple services, APIs, and human approvals over hours or days, what happens when something fails? Temporal provides durable execution — your workflow code automatically survives process crashes, server restarts, and network failures without any manual recovery logic.
With over 20,000 GitHub stars, Temporal is used by Snap, Netflix, Stripe, Datadog, and HashiCorp. It was created by the engineers behind Uber Cadence and brings the same battle-tested technology that powered 100+ critical Uber services.
What Temporal Does
Temporal separates your application logic (workflows and activities) from the reliability infrastructure. You write workflow code as regular functions — Temporal handles retries, timeouts, state persistence, and failure recovery. If a worker crashes mid-workflow, Temporal replays the workflow from where it left off.
Architecture Overview
[Application Code]
Workflows + Activities
|
[Temporal SDK]
Go, TypeScript, Python,
Java, .NET, PHP
|
[Temporal Workers]
Execute workflow and
activity functions
|
[Temporal Server]
+-------+-------+
| | |
[Frontend] [History] [Matching]
API gateway Workflow Task queue
gRPC/HTTP state routing
storage
|
[Database]
PostgreSQL, MySQL,
Cassandra, or SQLite
|
[Temporal Web UI]
Workflow visibility,
debugging, managementSelf-Hosting & Configuration
# Python SDK example
from temporalio import workflow, activity
from temporalio.client import Client
from temporalio.worker import Worker
from datetime import timedelta
import asyncio
@activity.defn
async def charge_payment(order_id: str, amount: float) -> str:
# This runs with automatic retries on failure
result = await payment_api.charge(order_id, amount)
return result.transaction_id
@activity.defn
async def send_confirmation(email: str, order_id: str) -> None:
await email_service.send(email, f"Order {order_id} confirmed")
@activity.defn
async def ship_order(order_id: str) -> str:
tracking = await shipping_api.create_shipment(order_id)
return tracking.tracking_number
@workflow.defn
class OrderWorkflow:
@workflow.run
async def run(self, order_id: str, email: str, amount: float) -> dict:
# Each step is durable — survives crashes
tx_id = await workflow.execute_activity(
charge_payment, args=[order_id, amount],
start_to_close_timeout=timedelta(seconds=30),
)
await workflow.execute_activity(
send_confirmation, args=[email, order_id],
start_to_close_timeout=timedelta(seconds=10),
)
# Wait up to 7 days for warehouse processing
tracking = await workflow.execute_activity(
ship_order, args=[order_id],
start_to_close_timeout=timedelta(days=7),
)
return {"tx_id": tx_id, "tracking": tracking}
async def main():
client = await Client.connect("localhost:7233")
# Start a workflow
result = await client.execute_workflow(
OrderWorkflow.run,
args=["order-123", "user@example.com", 99.99],
id="order-123",
task_queue="orders",
)
print(f"Order completed: {result}")
asyncio.run(main())Key Features
- Durable Execution — workflows survive crashes, restarts, and deployments
- Automatic Retries — configurable retry policies for activities
- Long-Running — workflows can run for seconds, hours, or months
- Visibility — web UI shows workflow state, history, and debugging info
- Multi-Language — SDKs for Go, TypeScript, Python, Java, .NET, PHP
- Signals & Queries — interact with running workflows externally
- Timers — durable timers that survive process restarts
- Versioning — safely update workflow code without breaking running instances
Comparison with Similar Tools
| Feature | Temporal | Celery | Inngest | Step Functions | Airflow |
|---|---|---|---|---|---|
| Durability | Core feature | Manual | Yes | Yes | No |
| Languages | 6 SDKs | Python | TypeScript | JSON/YAML | Python |
| Long-Running | Yes (months) | Limited | Yes | Yes | Limited |
| Workflow State | Automatic | Manual | Automatic | Automatic | DB-based |
| Self-Hosted | Yes | Yes | Cloud only | AWS only | Yes |
| Complexity | Moderate | Low | Low | Low | Moderate |
| Best For | Reliable workflows | Background jobs | Serverless jobs | AWS workflows | Data pipelines |
FAQ
Q: Temporal vs Celery — when should I use Temporal? A: Use Celery for simple background tasks (send email, resize image). Use Temporal when tasks span multiple services, need to run for hours/days, or require guaranteed completion — like order processing, subscription billing, or user onboarding flows.
Q: What is durable execution? A: Temporal automatically persists workflow state after each step. If a worker crashes, a new worker replays the workflow history and continues from the last completed step — as if nothing happened.
Q: Is Temporal free? A: Temporal Server is open source (MIT). Temporal Cloud is a managed service with pricing based on actions. Self-hosting is free but requires operational expertise.
Q: How does Temporal handle failures? A: Activities have configurable retry policies (max attempts, backoff). Workflows can catch activity failures and run compensation logic (saga pattern). The workflow itself never fails from infrastructure issues.
Sources
- GitHub: https://github.com/temporalio/temporal
- Documentation: https://docs.temporal.io
- Website: https://temporal.io
- Created by Temporal Technologies (ex-Uber Cadence team)
- License: MIT