⚡
SelfHostStackOpen-Source Directory

Why Migrate Away from Temporal Cloud & AWS Step Functions?

Temporal Cloud and AWS Step Functions bill directly on workflow state transitions, execution actions, and persisted execution history. High-throughput microservice architectures executing millions of events, asynchronous checkout flows, or distributed ETL pipelines incur exponential monthly bills. AWS Step Functions charges $25 per million state transitions, meaning a 40-step workflow running 100,000 times a day costs over $3,000 monthly in execution fees alone. Self-hosting Temporal Server or Kestra gives you complete durable workflow execution, automatic state replay, infinite distributed retries, and comprehensive DAG scheduling on fixed-cost infrastructure with zero per-step execution metering.

Technical Architecture & Migration Analysis

SaaS workflow orchestration tools like AWS Step Functions and Temporal Cloud meter every state transition, timer tick, and activity dispatch. In microservice architectures processing millions of asynchronous transactions, these costs compound exponentially. Self-hosted workflow engines decouple business logic from infrastructure costs. Temporal Server uses event sourcing to record deterministic state changes in PostgreSQL, allowing worker applications in any programming language to resume workflows seamlessly after network faults or process restarts. Kestra provides a declarative YAML-first DAG engine with embedded Docker execution. Both architectures deliver enterprise-grade durability and observability at fixed VPS costs.

⚠️

When NOT to Migrate (When Staying on Temporal Cloud & AWS Step Functions Makes Sense)

Self-hosting is not universally the right move. Keep paying for SaaS if your team hits any of these constraints:

  • ▸Your workflow dependencies are tightly coupled to proprietary AWS IAM roles, EventBridge rules, and serverless Lambda bindings.
  • ▸Your team lacks experience maintaining PostgreSQL or MySQL database clusters with regular backups and WAL archiving.
  • ▸You require zero-ops multi-region active-active cluster failover without dedicated SRE oversight.

Real-World Cost Comparison: Temporal Cloud & AWS Step Functions vs Self-Hosted

Comparing vendor cloud billings against standard Hetzner / DigitalOcean infrastructure costs at scale.

Tier / ScaleTemporal Cloud & AWS Step Functions CostSelf-Hosted VPS CostEstimated Annual SavingsTechnical Breakdown
Startup / Microservices (1M Executions/Month)
1,000,000 workflow state transitions/month, 10 microservices
$1,200-$4,800/year (Step Functions state transitions + Temporal Cloud storage)€7.05/month (€84.60/year on Hetzner CPX21)$1,115-$4,715/yearSingle 4GB VPS running Temporal Server + PostgreSQL backing all services.
Growth / Data Pipelines (20M Executions/Month)
20M state transitions/month, complex DAG pipelines, webhook triggers
$6,000-$24,000/year (AWS Step Functions / Temporal Cloud Action credits)€14.28/month (€171.36/year on Hetzner CPX31)$5,828-$23,828/yearSelf-hosted Temporal or Kestra instance managing high-concurrency tasks.
Enterprise (200M+ Executions/Month)
200M+ state transitions/month, mission-critical financial/order sagas
$60,000-$180,000+/year (Enterprise Temporal Cloud contract / Step Functions)€150/month (€1,800/year on clustered PostgreSQL + Temporal nodes)$58,200-$178,200+/yearHA Temporal Server cluster with dedicated Postgres replication.

Top 4 Recommended Open-Source Replacements

Tested, self-contained, and production-ready. Click any tool to inspect verified docker-compose configurations, hardware sizing, and deployment guides.

Temporal Server (Self-Hosted)

MIT⭐ 23.3k+

Industry-standard open-source durable execution platform enabling resilient code-as-workflows in TypeScript, Go, Python, and Java.

Min RAM2 GB
Min CPU2 vCPU
GitHub Repo ↗

✅ Advantages

  • Full programmatic expressiveness: use standard loops, conditionals, and libraries in workflows
  • Eliminates distributed state bugs, manual database checkpointing, and bespoke retry queues
  • Huge ecosystem used by Netflix, Uber, Stripe, and thousands of tech companies

⚠️ Trade-offs / Limitations

  • Developers must understand workflow determinism constraints and SDK conventions
  • Requires maintaining an underlying PostgreSQL/MySQL database for event history storage

Core Features

▸Code-as-workflows: write orchestration logic in TypeScript, Python, Go, or Java with full IDE autocomplete
▸Automatic failure recovery and exponential backoff retry policies without manual queue management
▸Durable timers spanning seconds to months with guaranteed execution across process restarts
▸Real-time Temporal Web UI for visual inspection of workflow execution history and stack traces
▸gRPC-based high-throughput worker communication architecture with task queue routing
▸Comprehensive saga pattern support for distributed compensating transactions
▸MIT open-source license with zero per-execution or per-state-transition fees

Architecture Notes

Durable execution engine written in Go. Workflows are defined entirely as standard code (TypeScript, Python, Go, Java) rather than JSON/YAML DSLs. Temporal Server manages task queues, timer scheduling, and deterministic event history persistence (using PostgreSQL, MySQL, or Cassandra). Workers poll task queues via gRPC, execute activities, and checkpoint state transitions. If a worker fails, Temporal automatically reconstructs the workflow execution state from event history.

Known Limitations

Workflows must be strictly deterministic (random numbers, time calls, and network I/O must be isolated in Activities). Requires an external database (PostgreSQL or MySQL) for persistence.

Official Documentation ↗
📄 docker-compose.yml
Production Ready
version: '3.8'
services:
  temporal-db:
    image: postgres:15-alpine
    container_name: temporal-db
    restart: always
    environment:
      POSTGRES_USER: temporal
      POSTGRES_PASSWORD: temporal_db_password_2026
      POSTGRES_DB: temporal
    volumes:
      - temporal_pgdata:/var/lib/postgresql/data
    networks:
      - selfhost_net

  temporal:
    image: temporalio/auto-setup:latest
    container_name: temporal-server
    restart: always
    ports:
      - "7233:7233"
    environment:
      - DB=postgresql
      - DB_PORT=5432
      - POSTGRES_USER=temporal
      - POSTGRES_PWD=temporal_db_password_2026
      - POSTGRES_SEEDS=temporal-db
      - DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development_es.yaml
    depends_on:
      - temporal-db
    networks:
      - selfhost_net

  temporal-ui:
    image: temporalio/ui:latest
    container_name: temporal-ui
    restart: always
    ports:
      - "8080:8080"
    environment:
      - TEMPORAL_ADDRESS=temporal:7233
      - TEMPORAL_CORS_ORIGINS=http://localhost:8080
    depends_on:
      - temporal
    networks:
      - selfhost_net

volumes:
  temporal_pgdata:

networks:
  selfhost_net:
    external: true

🚀 5-Minute Deployment Guide

  1. 1Provision a VPS with at least 4GB RAM and 2 vCPUs (e.g. Hetzner CPX21).
  2. 2Install Docker: `curl -fsSL https://get.docker.com | sh`.
  3. 3Create project directory: `mkdir -p /opt/temporal && cd /opt/temporal`.
  4. 4Save the docker-compose.yml configuration above.
  5. 5Launch Temporal Server and Web UI: `docker compose up -d`.
  6. 6Open `http://your-server-ip:8080` to access the Temporal Web dashboard.
  7. 7Point your application SDK workers to `your-server-ip:7233` and register your namespace.

Recommended Cloud VPS for Temporal Server (Self-Hosted)

Compare all VPS hosts →
Hetzner Cloud€7.05/mo

CPX21 (3 vCPU, 4GB RAM, 80GB NVMe)

Excellent performance for Temporal Server handling millions of monthly executions.

Deploy on Hetzner →
DigitalOcean$24.00/mo

Basic Droplet (2 vCPU, 4GB RAM, 80GB SSD)

Reliable hosted environment with fast gRPC network connectivity.

Claim $200 DO Credit →

Kestra

Apache-2.0⭐ 28.3k+

Infinitely scalable declarative workflow and orchestration platform with 600+ plugins, real-time visual DAG editor, and event-driven triggers.

Min RAM2 GB
Min CPU2 vCPU
GitHub Repo ↗

✅ Advantages

  • Fast onboarding: create complex data pipelines in minutes using declarative YAML + visual editor
  • Executes embedded scripts inside ephemeral Docker containers without worker dependency conflicts
  • Unifies data engineering (Airflow/Prefect alternative) and microservice orchestration in one tool

⚠️ Trade-offs / Limitations

  • Enterprise features (SSO/RBAC) require commercial license for large organizations
  • JVM memory baseline of 1-2GB RAM requires at least 4GB total system memory

Core Features

▸Declarative YAML workflow definitions with embedded code scripts (Python, Node.js, Shell, SQL)
▸Interactive Web UI with visual DAG editor, real-time Gantt execution charts, and metrics
▸600+ pre-built plugins for cloud providers, databases, message brokers, and APIs
▸Event-driven execution via webhooks, Kafka messages, S3 file creation, and cron triggers
▸Integrated revision history and Git synchronization for workflow versioning
▸Sub-millisecond task dispatch with microsecond execution queuing
▸Apache-2.0 open-source core with zero per-task or per-schedule execution fees

Architecture Notes

Modern open-source orchestrator written in Java/Micronaut. Designed for both code-centric and low-code data/infrastructure workflows. Workflows are declared as clean YAML manifests with an integrated Monaco code editor, visual DAG topology viewer, and real-time execution logs. Features an extensible plugin architecture supporting Docker, Kubernetes, AWS, GCP, Python, SQL, and Git. Can run standalone with PostgreSQL/MySQL or scale horizontally using Apache Kafka.

Known Limitations

Declarative YAML paradigm requires learning Kestra task syntax rather than writing raw imperative code everywhere. Complex custom logic requires wrapping scripts in Docker tasks or custom plugins.

Official Documentation ↗
📄 docker-compose.yml
Production Ready
version: '3.8'
services:
  kestra-postgres:
    image: postgres:15-alpine
    container_name: kestra-postgres
    restart: always
    environment:
      POSTGRES_DB: kestra
      POSTGRES_USER: kestra
      POSTGRES_PASSWORD: kestra_secure_pass_2026
    volumes:
      - kestra_pgdata:/var/lib/postgresql/data
    networks:
      - selfhost_net

  kestra:
    image: kestra/kestra:latest
    container_name: kestra
    restart: always
    ports:
      - "8080:8080"
    environment:
      KESTRA_CONFIGURATION: |
        datasources:
          postgres:
            url: jdbc:postgresql://kestra-postgres:5432/kestra
            username: kestra
            password: kestra_secure_pass_2026
            driverClassName: org.postgresql.Driver
        kestra:
          repository:
            type: postgres
          queue:
            type: postgres
          storage:
            type: local
            local:
              base-path: /app/storage
    volumes:
      - kestra_storage:/app/storage
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - kestra-postgres
    networks:
      - selfhost_net

volumes:
  kestra_pgdata:
  kestra_storage:

networks:
  selfhost_net:
    external: true

🚀 5-Minute Deployment Guide

  1. 1Provision a VPS with at least 4GB RAM (e.g. Hetzner CPX21).
  2. 2Install Docker: `curl -fsSL https://get.docker.com | sh`.
  3. 3Create working directory: `mkdir -p /opt/kestra && cd /opt/kestra`.
  4. 4Save the docker-compose.yml configuration above.
  5. 5Launch Kestra: `docker compose up -d`.
  6. 6Open your browser at `http://your-server-ip:8080` to access the Kestra UI.
  7. 7Create your first flow from the guided templates in the visual editor.

Recommended Cloud VPS for Kestra

Compare all VPS hosts →
Hetzner Cloud€7.05/mo

CPX21 (3 vCPU, 4GB RAM, 80GB NVMe)

Great performance with NVMe storage for fast workflow state transitions.

Deploy on Hetzner →
DigitalOcean$24.00/mo

Basic Droplet (2 vCPU, 4GB RAM, 80GB SSD)

Convenient deployment with Docker container execution support.

Claim $200 DO Credit →

Argo Workflows

Apache-2.0⭐ 17.0k+

Kubernetes-native workflow engine using CRDs; each workflow is a custom resource running as a pod.

Min RAM2 GB
Min CPU2 vCPU
GitHub Repo ↗

✅ Advantages

  • No external DB — workflow state lives in etcd via CRDs
  • Scales horizontally with the underlying k8s cluster
  • Battle-tested by Intuit, Adobe, Mercedes-Benz, and BlackRock for batch jobs

⚠️ Trade-offs / Limitations

  • Requires a running k8s cluster (k3s works for single-node setups but adds operational surface)
  • Workflow logs disappear when the pod is garbage-collected unless artifact store is configured

Core Features

▸Kubernetes-native: every workflow is a CRD with kubectl-visible status
▸DAG and step-based execution with retries, loops, conditionals, and parameter passing
▸Native artifact storage using S3/GCS/MinIO between workflow steps
▸Web UI for live logs, retry/resume, parameter submission, and cron triggers
▸Embedded workflow templates and Workflow-of-Workflows for reuse
▸Sidecar/daemon containers for init tasks (git clone, secret mount, vault sync)

Architecture Notes

Kubernetes-native orchestrator that models workflows as Custom Resource Definitions (Workflow CRD) running directly inside a k8s cluster. Uses container steps as workflow tasks with native artifact passing between pods, persistent volumes, and resource quotas.

Known Limitations

Requires a Kubernetes cluster (cannot run on a single VPS without k3s/k0s); workflow logs are tied to pod lifecycle and persist only as long as the Workflow CRD.

Official Documentation ↗
📄 docker-compose.yml
Production Ready
version: '3.8'
services:
  argo-workflows-server:
    image: quay.io/argoproj/workflow-controller:v3.5.0
    container_name: argo-server
    restart: always
    ports:
      - "2746:2746"
    command:
      - server
      - --secure=false
    networks:
      - selfhost_net

  argo-workflows-controller:
    image: quay.io/argoproj/workflow-controller:v3.5.0
    container_name: argo-workflows-controller
    restart: always
    command:
      - --namespaced
    networks:
      - selfhost_net

networks:
  selfhost_net:
    external: true

🚀 5-Minute Deployment Guide

  1. 1Provision a k3s single-node cluster
  2. 2Install Argo Workflows manifests v3.5.0
  3. 3Port-forward the UI
  4. 4Submit a sample hello-world workflow
  5. 5Expose the UI behind an Ingress with TLS

Recommended Cloud VPS for Argo Workflows

Compare all VPS hosts →
Hetzner Cloud€29.00/mo

CCX23 (4 dedicated vCPU, 16GB RAM, 160GB NVMe)

Single-node k3s cluster runs Argo Workflows controller + UI comfortably with headroom for worker pods.

Deploy on Hetzner →

Apache Airflow

Apache-2.0⭐ 47.0k+

Python-based DAG scheduler for batch ETL and data pipelines; mature operator ecosystem and battle-tested at hyperscale.

Min RAM4 GB
Min CPU2 vCPU
GitHub Repo ↗

✅ Advantages

  • Most mature battle-tested open-source orchestrator (10+ years, 47k+ stars, 30+ provider companies)
  • Python-native DAGs integrate cleanly with pandas, dbt, PySpark
  • Best-in-class observability: built-in task duration tracking, SLA misses, and failure alerts

⚠️ Trade-offs / Limitations

  • Heavy resource footprint vs newer DAG tools (4GB+ RAM for scheduler + webserver + DB)
  • Not suited for event-driven or long-running workflows (use Temporal for those)

Core Features

▸Python-coded DAGs with full IDE support, type checking, and unit testing
▸Massive operator ecosystem: 1000+ providers (Kubernetes, Docker, Spark, BigQuery, Snowflake, Slack)
▸Multiple executor backends: LocalExecutor, CeleryExecutor, KubernetesExecutor, CeleryKubernetesExecutor
▸Web UI with graph view, gantt chart, calendar, task duration analytics, and log inspection
▸Robust backfill engine to recompute date ranges with catchup=True and rerun failed tasks
▸Native connections/secrets backend (AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault)

Architecture Notes

Python-coded DAG scheduler with a rich operator ecosystem (KubernetesPodOperator, DockerOperator, PythonOperator, HttpOperator). Uses PostgreSQL/MySQL metadata DB; executor types: LocalExecutor, CeleryExecutor, KubernetesExecutor.

Known Limitations

Not designed for long-running durable workflows spanning weeks/months; suitable primarily for batch ETL with finite jobs. Task duration is constrained by executor worker timeout.

Official Documentation ↗
📄 docker-compose.yml
Production Ready
version: '3.8'
services:
  postgres:
    image: postgres:15-alpine
    container_name: airflow-postgres
    restart: always
    environment:
      POSTGRES_DB: airflow
      POSTGRES_USER: airflow
      POSTGRES_PASSWORD: airflow_secure_pass_2026
    volumes:
      - airflow_pgdata:/var/lib/postgresql/data
    networks:
      - selfhost_net

  airflow-init:
    image: apache/airflow:2.9.3
    container_name: airflow-init
    restart: "no"
    environment:
      AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: postgresql+psycopg2://airflow:airflow_secure_pass_2026@postgres:5432/airflow
      AIRFLOW__CORE__EXECUTOR: LocalExecutor
      AIRFLOW__CORE__LOAD_EXAMPLES: "false"
    command: >
      sh -c "airflow db migrate && airflow users create --username admin --firstname Admin --lastname User --role Admin --email admin@localhost --password admin"
    depends_on:
      - postgres
    networks:
      - selfhost_net

  airflow-webserver:
    image: apache/airflow:2.9.3
    container_name: airflow-webserver
    restart: always
    ports:
      - "8080:8080"
    environment:
      AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: postgresql+psycopg2://airflow:airflow_secure_pass_2026@postgres:5432/airflow
      AIRFLOW__CORE__EXECUTOR: LocalExecutor
      AIRFLOW__CORE__LOAD_EXAMPLES: "false"
    command: webserver
    depends_on:
      - airflow-init
    networks:
      - selfhost_net

  airflow-scheduler:
    image: apache/airflow:2.9.3
    container_name: airflow-scheduler
    restart: always
    environment:
      AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: postgresql+psycopg2://airflow:airflow_secure_pass_2026@postgres:5432/airflow
      AIRFLOW__CORE__EXECUTOR: LocalExecutor
    command: scheduler
    depends_on:
      - airflow-init
    networks:
      - selfhost_net

volumes:
  airflow_pgdata:

networks:
  selfhost_net:
    external: true

🚀 5-Minute Deployment Guide

  1. 1Provision Hetzner CPX21 (4GB RAM, 4 vCPU) for single-node LocalExecutor
  2. 2Create docker-compose.yml with postgres, airflow-init, airflow-webserver, airflow-scheduler services
  3. 3Run docker compose up airflow-init to bootstrap DB schema
  4. 4Launch docker compose up -d
  5. 5Access UI at port 8080 (default admin/admin, change immediately)
  6. 6Mount DAGs folder, scheduler picks up every 5 minutes

Recommended Cloud VPS for Apache Airflow

Compare all VPS hosts →
Hetzner Cloud€14.28/mo

CPX21 (3 vCPU, 4GB RAM, 80GB NVMe)

Comfortable single-node host for Airflow scheduler + webserver + Postgres for low/moderate DAG volume.

Deploy on Hetzner →

Quick Specification Matrix

ToolLicenseMin RAMMin CPUGitHub RepoPrimary Advantage
Temporal Cloud & AWS Step Functions (Proprietary)Proprietary ClosedManaged CloudManaged CloudN/ATurnkey onboarding with vendor lock-in & paywalls
Temporal Server (Self-Hosted)MIT2 GB2 vCPUtemporalio/temporalFull programmatic expressiveness: use standard loops, conditionals, and libraries in workflows
KestraApache-2.02 GB2 vCPUkestra-io/kestraFast onboarding: create complex data pipelines in minutes using declarative YAML + visual editor
Argo WorkflowsApache-2.02 GB2 vCPUargoproj/argo-workflowsNo external DB — workflow state lives in etcd via CRDs
Apache AirflowApache-2.04 GB2 vCPUapache/airflowMost mature battle-tested open-source orchestrator (10+ years, 47k+ stars, 30+ provider companies)

Performance Benchmarks & Hard Operational Limits

Real-world operational trade-offs, resource consumption limits, and measured throughput.

Benchmark MetricTemporal Cloud & AWS Step Functions BaselineSelf-Hosted Alternative MetricOperational Bottleneck / LimitSource
State Transition Latency (Workflow Checkpoint)25ms-80ms (AWS Step Functions / Temporal Cloud across internet WAN)2ms-8ms (Temporal Server with local PostgreSQL NVMe)Database commit write latency and gRPC network roundtrip.Production Test
Cost per 1 Million Workflow State Transitions$25.00 (AWS Step Functions standard) or $25-$50 (Temporal Cloud Actions)$0.00 (Zero marginal software cost — fixed server hardware only)VPS CPU and memory utilization.Production Test
Workflow Execution History Retention30-90 days standard (additional storage cost per GB-month)Indefinite / Custom configured via PostgreSQL archiving policiesAvailable database disk storage capacity.Production Test

Frequently Asked Questions

Practical deployment, migration, and maintenance answers.

What is the key difference between Temporal and Airflow/Kestra?▾

Airflow and Kestra are primarily DAG-based orchestrators designed for scheduled data pipelines and batch ETL jobs using YAML/Python scripts. Temporal is a general-purpose durable execution engine designed for microservices, financial sagas, and interactive transactional workflows where code runs continuously and handles retries, timers, and external signals.

Can I use Temporal Server with TypeScript, Python, and Go in the same system?▾

Yes. Temporal Server communicates via standard gRPC APIs. You can have TypeScript workers handling frontend workflows, Python workers running ML tasks, and Go workers processing high-throughput backend tasks, all coordinated by the same self-hosted Temporal Server.

How does Temporal handle long-running workflows spanning weeks or months?▾

Temporal uses durable timers and deterministic event sourcing. When a workflow sleeps for 30 days (`await sleep('30 days')`), Temporal persists the timer in the database and shuts down in-memory worker state. When the timer fires 30 days later, Temporal reawakens the worker and continues execution from the exact line of code.

How easy is it to back up a self-hosted Temporal instance?▾

All workflow execution history and state is stored inside the PostgreSQL or MySQL database. Backing up the database using standard tools like `pg_dump` or continuous WAL archiving completely backs up all active and past workflows.

What happens to in-flight workflows if my server crashes or reboots?▾

When Temporal Server restarts and workers reconnect, Temporal replays the recorded event history from the database to reconstruct each workflow's state up to the last successful activity checkpoint. Workflows automatically resume without data loss or duplicate activity executions.

Starter Stack Pack — $29

Skip the setup: get the production-ready stack

Don't stitch together configs from five different READMEs. Get all 5 production-hardened Docker Compose stacks — Postgres, Redis, SSL auto-renewal, and backup scripts — ready to deploy in minutes.

⚡n8nVisual workflow automation
📊UmamiPrivacy-first web analytics
🛡️Uptime KumaUptime monitoring & alerts
🔐VaultwardenBitwarden-compatible vault
☁️NextcloudDropbox/Drive replacement
Get the Stack Pack — $29 →

One-time purchase · Instant download · Production-ready

esc
↑↓ navigate↵ open