Skip to content
Published on

워크플로우 엔진 2026 — Temporal·Inngest·Trigger.dev·Hatchet·Restate·DBOS·Airflow 심층 비교 (Durable Execution 시대의 좌표)

Authors

프롤로그 — 워크플로우는 왜 다시 1군 인프라가 되었나

2018년쯤 워크플로우 엔진은 "데이터 팀이 cron 대체로 쓰는 Airflow" 정도로 통했다. 백엔드 엔지니어들이 매일 들여다보는 단어는 아니었다. 2026년 5월 지금, 같은 카테고리가 갑자기 모든 백엔드 팀의 1군 인프라로 올라왔다. 이유는 단순하다 — AI 에이전트가 long-running operation을 강제했기 때문이다.

LLM 호출 한 번이 5초 걸리던 시절은 끝났다. 에이전트는 도구를 6개 부르고, 사용자 승인을 기다리고, 다음 단계로 넘어가기 전에 다른 시스템에서 결과를 폴링한다. 한 사이클이 30초, 5분, 어떤 경우엔 2시간이다. 동시에 retry·idempotency·replay가 옵션이 아니라 필수다. 모델은 한 번에 1퍼센트 확률로 throw하고, OpenAI/Anthropic API는 가끔 429를 던지고, 사용자는 그 사이에 탭을 닫는다. 그래서 "long-running·resumable·idempotent" 라는 세 조건을 한 번에 풀어주는 도구가 곧 워크플로우 엔진이고, 이 카테고리가 2026년에 다시 핵심이 되었다.

이 글은 2026년 5월 현재 워크플로우 엔진 12개 — Temporal·Inngest·Trigger.dev·Hatchet·Restate·DBOS·Cadence·Airflow·Prefect·Dagster·Argo·Conductor — 의 지도를 한 번에 그린다. 무엇이 같고 무엇이 다른가, AI 에이전트·결제·ETL·온보딩 중 어떤 워크로드에 누구를 골라야 하나, 그리고 한국·일본 현장은 무엇을 쓰고 있나.


1장 · 2026년의 워크플로우 엔진 지도

먼저 한 줄 요약. 워크플로우 엔진은 두 갈래로 나뉘었다. 한쪽은 백엔드 비즈니스 로직 진영 — Temporal·Inngest·Trigger.dev·Hatchet·Restate·DBOS·Cadence·Conductor. 다른 쪽은 데이터 엔지니어링 진영 — Airflow·Prefect·Dagster·Argo. 두 진영은 같은 "DAG 실행" 개념을 공유하지만 사용처도, 인터페이스도, 운영 모델도 다르다.

2026년 5월 기준 좌표.

엔진진영핵심 모델백엔드1차 SDK라이선스
Temporal비즈니스 로직Workflow as code · Event SourcingCassandra·Postgres·MySQL·SQLiteGo·Java·TS·Python·.NET·PHP·RubyMIT
Inngest비즈니스 로직Event-driven · 서버리스 친화자체TypeScript·Python·GoSource Available
Trigger.dev v3비즈니스 로직Task as code · Vercel 스타일 DXPostgres·자체TypeScriptApache 2.0
Hatchet비즈니스 로직Postgres-backed 큐 + 워크플로우PostgresTypeScript·Python·GoMIT
Restate비즈니스 로직Virtual Objects · 결정론적 실행자체 (Rust)TypeScript·Java·Kotlin·Go·Rust·PythonBSL → Apache 2.0 (4년)
DBOS비즈니스 로직DB-resident control planePostgresTypeScript·PythonMIT
Cadence비즈니스 로직Temporal 조상Cassandra·MySQLGo·JavaApache 2.0
Conductor (Orkes)비즈니스 로직JSON DSL · 마이크로서비스 orchestrationRedis·Cassandra·Postgres다국어 HTTPApache 2.0
Airflow 3데이터 엔지니어링Python DAG · scheduler 분리Postgres·MySQLPythonApache 2.0
Prefect 3데이터 엔지니어링Pythonic flow · 동적 DAGPostgres·SQLitePythonApache 2.0
Dagster 1.10데이터 엔지니어링Asset-centric (DAG가 아니라 자산)Postgres·SQLitePythonApache 2.0
Argo Workflows데이터 엔지니어링k8s 네이티브 · YAML/CRDetcd (k8s)YAML·PythonApache 2.0

핵심 통찰 3개.

첫째, 비즈니스 로직 진영의 폭발이 더 크다. AI 에이전트·결제·온보딩·구독 같은 long-running 백엔드 로직이 이전엔 BullMQ나 SQS+Lambda 같은 큐로 풀어왔는데, 2024~2026년에 이 패턴 자체가 너무 깨지기 쉽다는 합의가 굳어졌다. 그래서 Temporal·Inngest·Trigger.dev·Hatchet·Restate·DBOS가 한꺼번에 떴다.

둘째, 데이터 엔지니어링 진영은 안정기다. Airflow는 2024년 10월 Airflow 3.0이 나오면서 scheduler·executor 분리를 마무리했고, Prefect는 3.0(2024 Q3)에서 dynamic DAG의 결정판을 들고 왔고, Dagster는 자산(asset) 모델로 차별화를 완성했다. 새 진입자가 없다는 게 아니라, 카테고리 안에서 위치가 거의 굳었다.

셋째, "Workflow as code"가 표준 디자인 패턴이 되었다. 2018년의 워크플로우는 JSON·YAML·시각 에디터로 정의됐다(Step Functions·Airflow DSL·Conductor JSON). 2026년의 워크플로우는 Go·TS·Python 코드로 정의된다. 이유는 단순하다 — IDE 지원·타입 안정성·테스트 용이성·diff 가독성·코드리뷰가 전부 작동하기 때문이다. JSON DSL을 유지하는 Conductor 같은 도구조차 SDK 레이어를 함께 제공한다.


2장 · Durable Execution이란 — 재시작·재시도·멱등성·replay

본격적으로 엔진을 비교하기 전에, 이 카테고리를 묶는 한 단어 — durable execution — 을 풀어보자. 줄여 말하면 "워크플로우의 모든 진행 상태가 외부 저장소에 지속(persist)되어, 프로세스가 죽고 다시 살아나도 정확히 멈춘 자리에서 이어가는 실행 모델"이다. 이 정의가 함축하는 4가지 속성이 있다.

  1. 재시작(crash resumption) — 워커 프로세스가 OOM으로 죽거나 호스트가 재부팅돼도, 새 워커가 영구 저장된 이벤트 로그를 읽고 같은 워크플로우를 이어간다.
  2. 재시도(retries) — 워크플로우 안의 각 단계(activity·task)는 자동으로 실패 시 재시도된다. backoff·max attempts·timeout이 선언적으로 설정된다.
  3. 멱등성(idempotency) — 한 워크플로우 실행 ID에 대해 같은 액티비티가 중복 실행되더라도 결과는 동일하게 보장된다. 보통 워크플로우 ID + step ID 조합이 멱등 키 역할을 한다.
  4. 재현(replay) — 워크플로우 코드는 결정론적(deterministic)이어야 한다. 동일한 이벤트 로그를 재생하면 동일한 결정을 내려야 한다. 그래서 워크플로우 안에서 Math.random()이나 new Date()를 직접 부르지 않고, SDK가 제공하는 결정론적 버전을 쓴다.

왜 이게 중요한가. 일반적인 큐 + 워커 모델(BullMQ·Sidekiq·SQS+Lambda·RabbitMQ)을 떠올려보자. "사용자 가입 → 이메일 발송 → Stripe 고객 생성 → Salesforce 동기화" 같은 4단계 온보딩 워크플로우를 짠다고 하면 — 사실상 모든 백엔드 팀이 이 패턴을 손으로 구현해왔다. 큐 4개를 만들고, 각 워커가 다음 단계로 메시지를 던지고, 실패 시 DLQ로 보내고, 운영자가 DLQ를 들여다보고 재처리한다. 동작은 하지만 매번 다시 만든다. 그리고 매번 다음 같은 버그가 나온다.

  • "Stripe 고객은 만들어졌는데 Salesforce 동기화 직전에 워커가 죽었다 — 어디서부터 다시 실행하지?"
  • "이메일이 두 번 발송됐다 — 중복 처리는 어떻게 막지?"
  • "워크플로우 ID 별로 진행 상태를 어떻게 시각화하지?"
  • "온보딩 5단계로 늘어났는데 기존 in-flight 워크플로우는 어떤 버전으로 끝내야 하지?"

Durable execution 엔진은 이걸 라이브러리·플랫폼 레이어로 한 번에 풀어준다. 그래서 결제·온보딩·구독·AI 에이전트 같은 영역에서 폭발적으로 도입된다.


3장 · Temporal — 카테고리의 표준

Temporal부터 보자. 2019년 Maxim Fateev와 Samar Abbas — Uber에서 Cadence를 만든 사람들 — 가 따로 떨어져 나와 만든 회사다. 사실상 Cadence의 2세대다. 2026년 5월 기준 카테고리의 사실상 표준(de facto standard)이고, Snap·DoorDash·Datadog·Stripe·Coinbase·Box·Netflix(일부)·Hubspot이 production에서 굴린다.

핵심 모델은 단순하다 — 워크플로우 함수 = 결정론적 코드. 액티비티 = 부수효과(side effect) 있는 코드. 모든 워크플로우 함수 안의 결정(분기·sleep·signal 대기)은 이벤트 로그로 기록되고, 워크플로우 코드는 그 로그를 replay해 현재 상태를 복원한다. 그래서 워크플로우 함수는 어떤 외부 호출도 직접 하면 안 되고, 외부 호출은 모두 액티비티로 위임한다.

Go SDK로 짠 간단한 예.

package main

import (
    "context"
    "time"

    "go.temporal.io/sdk/workflow"
)

func OnboardingWorkflow(ctx workflow.Context, userID string) error {
    ao := workflow.ActivityOptions{
        StartToCloseTimeout: 10 * time.Second,
        RetryPolicy: &temporal.RetryPolicy{
            MaximumAttempts: 5,
            InitialInterval: time.Second,
            BackoffCoefficient: 2.0,
        },
    }
    ctx = workflow.WithActivityOptions(ctx, ao)

    if err := workflow.ExecuteActivity(ctx, SendWelcomeEmail, userID).Get(ctx, nil); err != nil {
        return err
    }
    if err := workflow.ExecuteActivity(ctx, CreateStripeCustomer, userID).Get(ctx, nil); err != nil {
        return err
    }
    if err := workflow.ExecuteActivity(ctx, SyncSalesforce, userID).Get(ctx, nil); err != nil {
        return err
    }
    return workflow.Sleep(ctx, 24*time.Hour) // 결정론적 sleep — 24시간 후 재개
}

이 코드가 신기한 이유는 workflow.Sleep(24*time.Hour)이 진짜로 24시간 잠든다는 점이다. 워커 프로세스는 그 사이에 죽었다 살아도 되고, 인프라가 재배포돼도 된다. 24시간 뒤 누군가가 같은 워크플로우 ID로 깨우면 SDK가 이벤트 로그를 replay해 이 자리부터 이어간다. 이것이 durable execution의 본질이다.

Temporal의 강점 — 다국어 SDK(Go·Java·TS·Python·.NET·PHP·Ruby가 GA), 7년간 쌓인 production 사례, 가장 큰 커뮤니티, Temporal Cloud의 SLA. 약점 — 자체 백엔드(Cassandra·Postgres·MySQL·SQLite)가 필요하고, 결정론 제약이 처음엔 직관적이지 않아 학습 곡선이 가파르다. 그리고 가격이 — Temporal Cloud 기준 — 액티비티 호출과 이벤트 건당 과금이라 트래픽이 많은 워크로드에선 청구서가 가파르게 오른다.

언제 Temporal을 고르나. 장기 운영할 미션 크리티컬 워크플로우, 다국어 폴리글랏 환경, 결제·정산·청구 같은 정합성이 절대적인 도메인, 이미 운영 인력이 있고 인프라 자체를 들고 가도 되는 회사.


4장 · Inngest — TS 친화, 서버리스 친화

Temporal이 "다국어·자체 인프라"라면, Inngest는 "TypeScript first·서버리스 친화"의 정반대 축이다. 2021년 창업, 본사 샌프란시스코. CEO Tony Holdstock-Brown은 GraphCMS·SoundCloud 출신. 핵심 통찰은 — "Vercel·Cloudflare·AWS Lambda에서 돌아가는 백엔드는 함수당 실행 시간이 짧다. 그래서 워크플로우를 서버리스 친화적으로 다시 설계해야 한다."

Inngest의 모델은 event-driven step function이다. 워크플로우를 JS 함수로 짜되, 각 단계(step.run, step.sleep, step.waitForEvent)는 Inngest 백엔드가 별도로 호출하는 단위다. 코드는 이렇게 생겼다.

import { Inngest } from "inngest";

export const inngest = new Inngest({ id: "my-app" });

export const onboarding = inngest.createFunction(
  { id: "user-onboarding" },
  { event: "user/signed-up" },
  async ({ event, step }) => {
    await step.run("send-welcome-email", async () => {
      await sendWelcomeEmail(event.data.userID);
    });

    await step.run("create-stripe-customer", async () => {
      await createStripeCustomer(event.data.userID);
    });

    await step.sleep("wait-1-day", "1d"); // 1일 휴면, 서버리스 환경에서도 작동

    await step.run("send-day-1-followup", async () => {
      await sendDayOneFollowup(event.data.userID);
    });
  }
);

이게 어떻게 작동하나. step.run이 호출되면 Inngest는 콜백을 실행하고, 결과를 자기 백엔드에 기록한다. 다음 step에 도달하면 함수가 종료되고, Inngest가 별도 HTTP 호출로 같은 함수를 다시 부른다. 이번엔 같은 워크플로우 인스턴스 ID로. SDK가 첫 step의 캐시된 결과를 보고, 다음 step만 새로 실행한다. 각 호출은 짧다 — Vercel의 Edge Function·Cloudflare Workers 같은 데서도 잘 돈다.

Inngest의 강점 — TS first, Vercel/Cloudflare 친화, Local Dev UI가 잘 만들어져 있고, 가격이 free tier가 후하다(월 5만 step). 약점 — 폴리글랏이 약하고(TS·Python·Go만), 결정론 제약은 Temporal보다 느슨한 대신 step 분할을 잘 못하면 성능이 안 나온다. 그리고 회사가 비교적 신생(2021)이라 enterprise 도입 trust는 Temporal에 못 미친다.

언제 Inngest를 고르나. TypeScript 단일 스택 SaaS, Vercel·Cloudflare·Netlify·Render 같은 서버리스 호스팅, 이벤트 중심으로 트리거되는 워크플로우, AI 에이전트 같은 "조금 길지만 엄청 길지는 않은" 작업.


5장 · Trigger.dev v3 — Vercel 스타일 DX

2022년 영국 런던 창업. 처음엔 Inngest와 비슷한 event-driven 모델이었지만, 2024년 v3로 갈아엎으면서 모델이 크게 바뀌었다. v3는 "task as code · 자체 워커 컨테이너" 모델이다. 즉 사용자가 task 코드를 작성하면 Trigger.dev 자체 인프라(또는 self-hosted)에서 격리된 컨테이너로 실행한다. 그래서 함수당 실행 시간 제약이 거의 없다(기본 1시간, 최대 24시간). Vercel Functions의 한계인 60초·5분 벽을 우회한다.

코드는 이렇게 생겼다.

import { task } from "@trigger.dev/sdk/v3";

export const onboardingTask = task({
  id: "user-onboarding",
  maxDuration: 3600, // 1시간
  run: async (payload: { userID: string }) => {
    await sendWelcomeEmail(payload.userID);

    const stripeCustomer = await createStripeCustomer(payload.userID);

    await wait.for({ seconds: 86400 }); // 1일 휴면

    await sendDayOneFollowup(payload.userID);

    return { stripeCustomer };
  },
});

DX의 핵심은 **"Vercel처럼 코드를 push하면 자동으로 빌드되고 트리거에 등록된다"**는 점이다. 별도 worker 프로세스를 관리할 필요가 없다(Trigger.dev Cloud 사용 시). v3에서 도입된 또 다른 차별점은 Realtime API — 워크플로우의 진행 상태를 클라이언트에서 실시간 구독할 수 있다. AI 에이전트 UI(ChatGPT처럼 한 단계씩 progress가 흐르는)를 만들 때 결정적인 기능이다.

강점 — DX가 가장 부드럽고(Vercel CLI 흉내), 1시간짜리 task를 그냥 돌릴 수 있고, Realtime API가 있고, self-host도 가능하다(Apache 2.0). 약점 — TS만 지원(Python·Go SDK는 2025년 베타지만 production 비중 낮음), 그리고 v2 → v3 마이그레이션이 거의 재작성에 가까워 v2 사용자들에게 부담을 줬다.

언제 Trigger.dev를 고르나. TS 풀스택 SaaS·인디 개발자·AI 에이전트 사이드 프로젝트, Vercel 스타일 DX를 원하는 팀, task 한 번 실행이 5분~1시간 범위, 그리고 클라이언트 UI에서 task 진행을 실시간으로 보여줘야 하는 제품(AI 에이전트 UI·긴 분석 작업·코드 생성기).


6장 · Hatchet — Postgres 기반의 신예

Hatchet는 2024년 Y Combinator 윈터 24 배치 출신. 창업자 Alexander Belanger·Gabriel Ruttner는 Porter 출신 인프라 엔지니어들. 핵심 논제는 단순하다 — "Postgres가 이미 큐·메시지 브로커·KV·트랜잭션 다 잘 한다. 새 인프라 컴포넌트(Kafka·Redis·Cassandra)를 도입하지 말고 Postgres를 control plane으로 쓰자."

Hatchet의 모델은 두 층이다. 태스크 큐(Hatchet Queue) + 워크플로우 엔진(Hatchet Workflows). 큐는 Postgres의 SELECT ... FOR UPDATE SKIP LOCKED 위에서 작동하는 분산 작업 디스패처고, 워크플로우는 그 위에 쌓인 DAG 엔진이다.

TypeScript 예.

import { Hatchet } from "@hatchet-dev/typescript-sdk";

const hatchet = Hatchet.init();

const onboarding = hatchet.workflow({
  name: "user-onboarding",
  on: { event: "user:signed-up" },
});

onboarding
  .step({ name: "send-email" }, async (ctx) => {
    await sendWelcomeEmail(ctx.input.userID);
    return { sent: true };
  })
  .step({ name: "create-stripe", parents: ["send-email"] }, async (ctx) => {
    return createStripeCustomer(ctx.input.userID);
  })
  .step({ name: "sync-salesforce", parents: ["create-stripe"] }, async (ctx) => {
    return syncSalesforce(ctx.input.userID);
  });

강점 — Postgres만 있으면 self-host가 단순하다. RabbitMQ·Kafka·Redis 모두 불필요. throughput도 좋고(2026년 5월 기준 단일 노드 초당 1만+ task), 가격이 매우 합리적이다(Hatchet Cloud free tier가 후하다). 약점 — 회사가 2024년 창업이라 production track record가 짧다. SDK는 TS·Python·Go가 있지만 Java·.NET이 없다. 그리고 Temporal급의 결정론적 replay까지는 가지 않는다(작업 멱등 보장은 있지만 코드 결정론은 사용자 책임).

언제 Hatchet를 고르나. 이미 Postgres가 있고 다른 인프라 컴포넌트를 늘리고 싶지 않을 때, self-host 우선, AI 에이전트·결제·온보딩 같은 백엔드 비즈니스 로직, Y 콤보 신생사를 trust하는 팀.


7장 · Restate — Rust 코어와 Virtual Objects

Restate는 2023년 베를린 창업, Apache Flink의 PMC 멤버였던 Stephan Ewen이 공동 창업했다. 코어가 Rust로 작성됐고, 디자인 철학은 — "durable execution + actor model을 한 번에 풀자". 핵심 추상이 Virtual Object다 — 분산 상태를 가진 객체로, 단일 키에 대해선 직렬화된 실행을 보장하면서 durable한 상태와 결정론적 동작을 함께 제공한다.

코드는 이렇게 생겼다.

import * as restate from "@restatedev/restate-sdk";

const cart = restate.object({
  name: "Cart",
  handlers: {
    addItem: async (ctx: restate.ObjectContext, item: string) => {
      const items = (await ctx.get<string[]>("items")) ?? [];
      ctx.set("items", [...items, item]);
    },
    checkout: async (ctx: restate.ObjectContext) => {
      const items = (await ctx.get<string[]>("items")) ?? [];
      const orderId = ctx.rand.uuidv4();
      await ctx.run("charge", () => stripeCharge(items));
      await ctx.run("ship", () => shipItems(items, orderId));
      ctx.clear("items");
      return orderId;
    },
  },
});

restate.endpoint().bind(cart).listen();

여기서 ctx.run("charge", ...)이 결정론적 멱등 실행 단위다. ctx.rand.uuidv4()도 replay 시 동일 값을 돌려준다. ctx.get/ctx.set은 객체 키 단위로 durable한 상태 저장.

강점 — actor model이 자연스럽고(IoT·게임·세션 관리에 잘 맞음), Rust 코어 덕에 latency가 낮고(2026 자체 벤치에서 p99 5ms 미만), self-host 운영이 단순하다(단일 바이너리 + RocksDB). 약점 — actor 패러다임에 익숙해야 한다. SDK는 TS·Java·Kotlin·Go·Rust·Python으로 늘었지만, 커뮤니티는 Temporal·Inngest보다 작다. 그리고 라이선스가 Business Source License(4년 후 Apache 2.0)이라 OSS 순수파에겐 신경 쓰일 부분이다.

언제 Restate를 고르나. 상태 있는 워크플로우(장바구니·세션·게임 매치메이커·IoT 장치 상태머신), 저지연(low-latency) 워크플로우, 단일 바이너리 self-host를 원하는 팀, Rust 인프라 친화 조직.


8장 · DBOS — Postgres = control plane

DBOS는 2022년 MIT·Stanford·CMU의 DB 연구자들이 공동 창업했다(Mike Stonebraker·Matei Zaharia·Joe Hellerstein이 자문). 논제는 매우 도발적이다 — "전통적인 OS의 역할을 DB가 대체할 수 있다. Postgres를 control plane으로 쓰면 워크플로우·메시징·KV·트랜잭션을 모두 한 번에 푼다."

DBOS의 코드 모델은 데코레이터 기반이다.

from dbos import DBOS, WorkflowContext

@DBOS.workflow()
def onboarding(ctx: WorkflowContext, user_id: str) -> None:
    DBOS.invoke(send_welcome_email, user_id)
    customer = DBOS.invoke(create_stripe_customer, user_id)
    DBOS.sleep(86400)  # 1일 휴면
    DBOS.invoke(send_day_one_followup, user_id, customer.id)

@DBOS.communicator()
def send_welcome_email(user_id: str) -> None:
    smtp_send(user_id)

내부적으로 @DBOS.workflow()는 함수 실행을 Postgres 트랜잭션 + 영구 이벤트 로그로 감싼다. 함수가 죽으면 다음 워커가 같은 워크플로우 ID로 깨워 멈춘 자리부터 이어간다. 모든 진행 상태가 Postgres에 산다. 그래서 별도 워크플로우 백엔드가 없다 — 너의 Postgres가 곧 워크플로우 엔진이다.

강점 — Postgres만 있으면 됨(별도 인프라 0개), 가벼움(워크플로우 엔진이 라이브러리), 학술적 디자인 정통성. 약점 — 회사·제품이 신생, throughput이 Postgres 한 인스턴스에 묶임(2026 기준 단일 노드 1000~3000 wf/s, partitioning 시 더 올라가지만 운영 복잡), 폴리글랏이 약함(TS·Python만).

언제 DBOS를 고르나. 모든 워크로드를 한 Postgres에 모으고 싶을 때, 연구·실험·소규모 SaaS에서 인프라 컴포넌트 수를 0에 가깝게 유지, TS/Python 단일 스택 팀.


9장 · Cadence — Uber의 조상, Temporal의 부모

Cadence는 2017년 Uber가 만들어 오픈소스화했다. 창업자 Maxim·Samar가 2019년 Temporal로 분기하면서 Cadence는 Uber 사내 운영팀이 계속 유지하고 있다. 2026년에도 Uber 내부에서 일평균 수십억 워크플로우 실행을 굴린다. API와 디자인이 Temporal과 매우 비슷하다(같은 사람들이 두 번째로 만든 게 Temporal이라 당연하다).

차이점은 — Cadence가 Temporal보다 보수적이다. SDK 다양성이 Temporal에 못 미치고(Go·Java가 주력), 새 기능 출시 속도가 느리다. 대신 Uber 안에서 검증된 7년+ track record가 있다. 외부 사용자는 거의 Temporal로 옮겼지만 Uber·Coinbase 일부·HashiCorp 일부가 여전히 Cadence를 굴린다.

언제 Cadence를 고르나. Uber 같은 초대형 운영팀이 있고 자체 운영을 선호하는 곳 — 사실상 대부분의 신규 도입은 Temporal로 간다.


10장 · Airflow / Prefect / Dagster — 데이터 엔지니어링 진영

비즈니스 로직 진영을 봤으니 데이터 엔지니어링 쪽으로 시선을 옮기자. 이 진영의 좌표는 Airflow·Prefect·Dagster 3강이다.

Airflow 3.0 (2024.10 GA). Airbnb가 2015년 만들어 Apache로 기증한 데이터 워크플로우 엔진. 2026년 5월 기준 데이터 엔지니어링의 사실상 표준. Airflow 3.0에서 가장 큰 변화는 — scheduler·DAG 처리기·executor가 완전히 분리되어 multi-tenant 운영이 쉬워졌다. Task SDK가 분리돼 워커가 더 가벼워졌다. Astro·MWAA(AWS Managed)·Cloud Composer(GCP)가 관리형 옵션을 제공한다.

from airflow.decorators import dag, task
from datetime import datetime, timedelta

@dag(schedule="@daily", start_date=datetime(2026, 1, 1), catchup=False)
def daily_etl():
    @task
    def extract():
        return fetch_from_source()

    @task
    def transform(data):
        return clean_and_aggregate(data)

    @task
    def load(transformed):
        write_to_warehouse(transformed)

    load(transform(extract()))

daily_etl()

Prefect 3.0 (2024.09 GA). PrefectHQ가 만든 Pythonic 워크플로우 엔진. Airflow의 정적 DAG 한계(컴파일 타임에 그래프가 고정됨)를 풀기 위해 dynamic DAG을 채택했다. 즉 워크플로우 안에서 런타임 조건에 따라 DAG가 달라질 수 있다. 3.0에서 가장 큰 변화는 — 자체 Postgres·SQLite 백엔드를 쓰는 단순화된 self-host 경험, 그리고 transactional 보장 강화.

Dagster 1.10 (2025 Q3). Elementl이 만든 자산(asset) 중심 워크플로우 엔진. 다른 두 도구가 "어떤 task가 언제 돌지"를 정의한다면, Dagster는 "어떤 자산(테이블·파일·모델)이 어떻게 갱신되는지"를 정의한다. 그래서 데이터 lineage·관측성이 1급이다. 1.10에서는 Software-Defined Asset 모델이 더 정교해지고, dbt·Snowflake·Databricks 통합이 1급이 됐다.

세 도구의 분기점.

  • Airflow — 가장 큰 커뮤니티·생태계·통합. 단점은 동적 DAG가 어렵고, 운영이 무겁고, scheduler 부하 이슈가 있었다(3.0에서 완화).
  • Prefect — Pythonic, dynamic, 학습 곡선이 부드럽다. 단점은 Airflow보다 통합 라이브러리가 적다.
  • Dagster — 자산 모델·lineage·관측성. 단점은 학습 곡선이 가팔라(자산 추상을 처음 보면 이해가 안 됨), 단순 cron 대체용으로는 과하다.

언제 어떤 걸 고르나. 이미 데이터 팀이 있고 Airflow 운영 노하우가 있다면 → Airflow 유지. 새 데이터 팀, Pythonic DX 중시 → Prefect. 데이터 lineage·관측성·자산 중심 사고 → Dagster.


11장 · Argo Workflows — k8s 네이티브

Argo Workflows는 Intuit이 만들어 CNCF에 기증한 Kubernetes 네이티브 워크플로우 엔진. 모든 워크플로우 단계가 k8s Pod로 실행되고, 워크플로우 정의가 CRD(Custom Resource Definition)다. ML pipeline·CI/CD·데이터 처리에 많이 쓰인다(Argo CD와는 다른 프로젝트지만 같은 회사 제품군이다).

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: ml-training-
spec:
  entrypoint: pipeline
  templates:
    - name: pipeline
      steps:
        - - name: preprocess
            template: preprocess-data
        - - name: train
            template: train-model
        - - name: evaluate
            template: evaluate-model
    - name: preprocess-data
      container:
        image: my-org/preprocess:latest
        command: [python, preprocess.py]
    - name: train-model
      container:
        image: my-org/train:v2
        command: [python, train.py]
        resources:
          limits:
            nvidia.com/gpu: 1

강점 — k8s 네이티브, 각 단계가 컨테이너라 언어/런타임에 구애받지 않음, ML/CI/CD 친화. 약점 — YAML로 표현이 빠르게 복잡해지고, 코드 기반 워크플로우보다 디버깅이 어렵다. 그리고 단계 시작에 Pod startup 오버헤드가 있어 짧은 task가 많은 워크플로우엔 비효율적.

언제 Argo를 고르나. 이미 k8s를 굴리고 있고 모든 인프라를 k8s 위에 통일하고 싶을 때, 단계가 독립 컨테이너인 ML/CI/데이터 pipeline, YAML로 정의가 자연스러운 단순 DAG.


12장 · Conductor — Netflix → Orkes

Conductor는 2016년 Netflix가 만들어 오픈소스화한 마이크로서비스 오케스트레이션 엔진이다. 2022년 원 창업자들이 Orkes를 차려 Conductor의 enterprise version과 Cloud을 출시했다. 모델은 JSON DSL — 워크플로우를 JSON으로 정의하고, 각 단계는 작업자(worker)가 HTTP 폴링으로 가져가 실행한다.

{
  "name": "user_onboarding",
  "version": 1,
  "tasks": [
    {
      "name": "send_welcome_email",
      "taskReferenceName": "send_email_ref",
      "type": "SIMPLE"
    },
    {
      "name": "create_stripe_customer",
      "taskReferenceName": "stripe_ref",
      "type": "SIMPLE"
    },
    {
      "name": "wait_one_day",
      "taskReferenceName": "wait_ref",
      "type": "WAIT",
      "inputParameters": {
        "duration": "1d"
      }
    }
  ]
}

각 task type에는 SIMPLE(워커 폴링), HTTP(REST 직접 호출), FORK_JOIN(병렬), SWITCH(분기), DECISION 등이 있다. Netflix 내부에서는 콘텐츠 인코딩 파이프라인·결제·푸시 알림 같은 대규모 비동기 워크로드를 굴렸다.

강점 — 언어 독립(JSON DSL이라 어떤 언어든 워커가 됨), 시각 에디터, Netflix 운영 검증. 약점 — JSON으로 정의가 길어지면 코드 리뷰가 어렵고, Workflow as code 시대 흐름에 역행한다. Orkes는 이를 보완하려 코드 SDK를 추가했지만 기본 모델은 여전히 JSON.

언제 Conductor를 고르나. 다국어 마이크로서비스 환경에서 언어 독립 오케스트레이션이 필요, 시각 에디터를 운영자에게 제공하고 싶을 때, Netflix 스타일 대규모 비동기 파이프라인.


13장 · 어떤 엔진을 골라야 하나 — 워크로드별 결정 트리

12개 엔진을 한 번씩 봤으니, 이제 워크로드별로 누가 어울리는지 매핑해보자.

AI 에이전트 / LLM 파이프라인

가장 핫한 워크로드. 한 사이클이 5초~30분 사이에 가변적이고, 외부 API(OpenAI·Anthropic·Replicate·도구 호출) 의존성이 크고, retry·idempotency가 필수, 클라이언트 UI에서 진행 상태를 보여줘야 한다.

  • 1순위 — Trigger.dev v3 또는 Inngest. TS first, Realtime API(Trigger), step model(Inngest)이 LLM 단계 분할과 자연스럽게 맞는다.
  • 2순위 — Temporal. Python·Go SDK로 LLM 호출을 워크플로우로 감싸기 좋고, replay 디버깅이 강력하다.
  • 3순위 — Hatchet. Postgres 단일 인프라가 매력적이라면.

결제 / 정산 / 청구

정합성·감사·재현가능성이 절대적인 도메인. retry 정책·중복 결제 방지·이벤트 로그가 핵심.

  • 1순위 — Temporal. 7년 production 검증, 결정론적 replay, 다국어 SDK. Stripe·Coinbase·DoorDash가 production에서 굴리는 도메인.
  • 2순위 — Cadence. Temporal 조상이라 같은 모델, Uber 내부 결제 운영.
  • 3순위 — Restate. Virtual Object 모델이 계좌·지갑 같은 상태 있는 결제에 자연스러움.

ETL / 데이터 엔지니어링

배치·스케줄·dependency 관리·dbt/Snowflake/Databricks 통합이 핵심.

  • 1순위 — Airflow. 표준, 가장 큰 통합 라이브러리. 이미 데이터 팀이 있다면 거의 자동선택.
  • 2순위 — Dagster. 자산 중심 모델, lineage·관측성이 필요할 때.
  • 3순위 — Prefect. Python 작은 팀, dynamic DAG 필요할 때.

사용자 온보딩 / 구독 / 알림

순서 있는 단계, 1~30일 휴면, 이벤트 트리거.

  • 1순위 — Inngest. event-driven 모델이 가장 자연스럽다.
  • 2순위 — Trigger.dev. TS 단일 스택이라면.
  • 3순위 — Temporal. 이미 Temporal을 굴리고 있다면.

ML 학습 / 추론 파이프라인

GPU 노드·컨테이너 격리·k8s 친화.

  • 1순위 — Argo Workflows. k8s 네이티브, 컨테이너 단계, GPU 리소스 선언.
  • 2순위 — Dagster + Modal 같은 GPU 백엔드 결합.
  • 3순위 — Temporal. 학습 자체보다 학습 orchestration 메타워크플로우.

마이크로서비스 오케스트레이션 (다국어)

언어 다양, JSON DSL이 자연스러움, 시각 에디터 필요.

  • 1순위 — Conductor (Orkes). JSON DSL, 다국어 워커.
  • 2순위 — Temporal. SDK 다양성으로 풀 수 있다면.

작은 SaaS · 인프라 컴포넌트 최소화

Postgres 외 인프라를 늘리고 싶지 않은 인디·소규모 팀.

  • 1순위 — Hatchet 또는 DBOS. 둘 다 Postgres가 control plane.
  • 2순위 — Inngest Cloud(별도 인프라 0개).

14장 · 한국·일본 도입 사례

이론은 충분히 봤다. 실제 production에서 누가 쓰는지 — 한국·일본 사례를 모아보자.

토스 (Toss · 한국)

토스는 2023~2024년에 결제·송금·증권 같은 정합성이 절대적인 도메인에서 Temporal 도입을 늘렸다. 공개 발표(2024 SLASH 토스 컨퍼런스)에서 토스증권은 주문·체결·정산 파이프라인의 일부를 Temporal로 옮기면서 retry·idempotency를 라이브러리화한 사례를 공유했다. 2026년 5월 기준 토스 그룹 내 여러 팀이 Temporal Cloud 또는 self-host Temporal을 굴린다. 데이터 엔지니어링 쪽은 별개로 Airflow.

우버 이츠 재팬 (Uber Eats Japan)

Uber 본진의 Cadence가 우버 이츠 일본 백엔드에도 깔려 있다. 주문·배차·결제 워크플로우 일부가 Cadence 위에서 돈다. 2024년 후반 Uber 내부 발표에서는 일부 도메인을 Temporal로 마이그레이션 중이라는 언급이 있었다.

LINE / LINE Yahoo

LINE은 자체 워크플로우 엔진을 오랫동안 굴려왔고, 2024년부터 일부 도메인에서 Argo Workflows와 Airflow를 도입한 흐름이 LINE Engineering 블로그에 공개됐다. 메시징·푸시 알림 같은 대규모 비동기 워크로드는 자체 큐 시스템(LINE Async)이 여전히 1군이지만, 결제·정산 쪽 신규 프로젝트에서 Temporal 검토가 진행 중이라는 비공식 보고가 있다.

Mercari (일본)

메르카리는 데이터 엔지니어링 쪽에서 Airflow를 표준으로 굴린다(Mercari Engineering 블로그에 다수 공개). 백엔드 비즈니스 로직은 자체 마이크로서비스·gRPC 중심이라 Temporal급 도구 도입은 제한적이지만, 일부 도메인(C2C 결제·검색 색인)에서 Apache Beam·Argo와 자체 워크플로우 라이브러리를 조합한다.

ZOZO (일본)

ZOZO는 검색·추천 인덱싱 파이프라인에서 Argo Workflows를 굴린다(ZOZO Tech 블로그). k8s 위에 모든 데이터·ML 파이프라인이 통일된 흔치 않은 사례.

CyberAgent (일본)

CyberAgent는 게임·미디어·광고 자회사가 많아 도구 다양성이 크다. 광고 입찰 도메인에서 Temporal 도입, 게임 백엔드 일부에 Cadence, 데이터 분석은 Airflow·Dagster 혼용. 발표 자료가 가장 풍부한 일본 회사 중 하나.


15장 · 정리 — 2026년의 워크플로우 엔진을 보는 5가지 관점

  1. AI 에이전트가 카테고리를 다시 1군 인프라로 끌어올렸다. 5초~30분 사이의 long-running·resumable·idempotent한 작업이 모든 백엔드의 일상이 되면서 큐 + 워커의 손코딩은 더 이상 답이 아니다.

  2. Workflow as code가 표준이 되었다. JSON·YAML DSL은 시각 에디터가 필요한 특수한 영역(Conductor·Argo)에 남고, 그 외에는 Go·TS·Python 코드가 1차 시민이다. IDE·타입·테스트·diff·리뷰가 다 작동하기 때문에 당연한 귀결이다.

  3. 두 진영의 구분이 점점 흐려진다. 비즈니스 로직 진영과 데이터 엔지니어링 진영은 여전히 분리되어 있지만, AI/ML 파이프라인이 둘 사이의 회색 지대를 만들었다. Temporal로 ML orchestration을 짜는 팀도, Dagster로 백엔드 비즈니스 워크플로우를 짜는 팀도 늘었다.

  4. 인프라 컴포넌트 최소화가 신호다. Hatchet·DBOS의 인기는 "Postgres만 있으면 다 한다"는 thesis의 부상이다. Kafka·Redis·Cassandra를 별도로 운영하는 부담을 줄이려는 흐름. Restate처럼 단일 바이너리 self-host도 같은 맥락.

  5. 선택은 결국 팀의 모양에 달려 있다. Temporal이 가장 "올바른" 답인 경우가 많지만, TS 단일 스택 SaaS에는 Inngest/Trigger.dev가 자연스럽고, k8s 진영에는 Argo가 어울리고, 데이터 팀에는 Airflow가 표준이다. "최고의 엔진"보다 "지금 팀에 맞는 엔진"이 정답이다.

2018년의 우리는 cron + 큐 + 워커로 모든 걸 처리했다. 2026년의 우리는 그 위에 durable execution이라는 한 층을 올렸다. 다음 한 줄을 짜기 전에 — 이 워크플로우가 1년 뒤에도 돌 거라면, 그건 워크플로우 엔진의 일이다.


참고 / References