Workspace IndexDev Notes › Temporal — where 'retry, idempotency, visibility into a stuck run' actually lives

#211PoC

Temporal — where 'retry, idempotency, visibility into a stuck run' actually lives

Temporal is durable workflow orchestration: it replays workflow code deterministically so a process that dies keeps its state, and retries, timeouts, compensations, and multi-day waits are first-class. It is the product the dual-write end-condition problem keeps describing — and a settlement flow that is long-running plus externally-waiting is the textbook fit, at the price of a determinism constraint that reshapes how the code is written.

Not yet scoped — the deliverable is a fit test on one real flow, not adopting a platform. Take a settlement or migration flow that already has a long-running, externally-waiting shape (submit → wait for confirmation → reconcile → release), and model it twice: once as the cron + state-table you would otherwise hand-build, once as a Temporal workflow. Compare on the four things Temporal sells — retries, idempotency, visibility into a stuck run, changing code mid-flight — and on the two costs it adds: the determinism constraint (no direct randomness, clock reads, or network calls in workflow code — they move to activities) and the operational bill (self-hosted worker cost vs Temporal Cloud per-action pricing, plus per-workflow event-history size, which grows replay cost). Alternatives to keep in the same table: Inngest (lighter for small backends), Restate, and the hand-rolled cron + state table itself. Source: Temporal — durable execution via deterministic replay.

Why

Temporal is the packaged answer to a question this catalogue keeps arriving at from different doors. The pattern is always the same: a process has to survive its own death mid-flight, retry the parts that failed without redoing the parts that succeeded, wait days for something external, and let an operator see where it is stuck. circuit-breaker-saga reached it from failure isolation; x402-settlement-retry reached it from payment retries; irreversible-switch-design reached it from the dual-write cutover that has an end date. Durable execution is the name of the thing all three were hand-building.

The mechanism is one idea — deterministic replay — and it is also the whole cost. Temporal does not persist your variables; it persists the history of events and re-runs your workflow code against that history to rebuild state, which is why a worker can be killed and resume exactly where it was. For that replay to be correct, the workflow code must be deterministic: no direct clock reads, no random numbers, no network calls inside the workflow — those move into 'activities' that are recorded and replayed as results. That constraint is not a detail; it reshapes how the code is written, and it is the honest reason to model a flow twice before adopting it.

It is a build-vs-buy decision with a fork this catalogue has drawn before. The hand-rolled cron + state table is exactly the 'conversation 2' option — it works, and for a small backend it may be the right amount of machinery. Temporal earns its weight when the flows are genuinely long-running and externally-waiting — which is precisely the settlement shape — and when the number of such flows is large enough that reimplementing retries and visibility per flow is the real cost. build-rent-or-own-the-rail is the same fork for payment rails; this is it for execution. The two costs to price against the four benefits are the event-history size per workflow and the determinism tax on the code.

How it works

The pattern three cards arrived at separately

Card Reached durable execution from
circuit-breaker-saga failure isolation / compensation
x402-settlement-retry retrying a payment safely
irreversible-switch-design the dual-write cutover with an end date

All three want: survive a crash, retry without double-spending, wait for external state, see where it is stuck.

Deterministic replay — the mechanism and its tax

How it works What it costs
State rebuilt by replaying event history, not stored as variables event-history size grows replay cost
Correctness requires deterministic workflow code no clock/random/network in workflow — move to activities
Resumption worker dies → resumes exactly where it was the reason to accept the constraint

Build vs buy

Option Good when
Hand-rolled cron + state table small backend, few flows
Temporal flows long-running + externally-waiting, many of them
Inngest / Restate lighter middle ground

Price the two costs (history size, determinism tax) against the four benefits (retry, idempotency, visibility, live code change).

Related cards

circuit-breaker-saga, x402-settlement-retry, irreversible-switch-design (the flows that want this), build-rent-or-own-the-rail (the same build-vs-buy fork, for rails).

← All Dev Notes · Workspace Index · Top ↑

Temporal — '재시도·멱등성·멈춘 실행의 가시성'이 실제로 사는 곳

Temporal은 내구성 있는 워크플로 오케스트레이션입니다 — 워크플로 코드를 결정론적으로 재생(replay)해 죽은 프로세스가 상태를 잃지 않게 하고, 재시도·타임아웃·보상 트랜잭션·며칠짜리 대기가 1급 개념입니다. 이중 쓰기 종료 조건 문제가 계속 묘사하던 바로 그 제품이고 — 장기 실행 + 외부 대기 패턴인 정산 플로우가 교과서적으로 맞습니다 — 코드 작성 방식을 바꾸는 결정론 제약을 대가로.

아직 범위 미정 — 산출물은 플랫폼 도입이 아니라 실제 플로우 하나에 대한 적합성 테스트입니다. 이미 장기 실행·외부 대기 모양(제출 → 확인 대기 → 대사 → 해제)을 가진 정산·마이그레이션 플로우를 골라 두 번 모델링합니다 — 한 번은 직접 만들 크론 + 상태 테이블로, 한 번은 Temporal 워크플로로. Temporal이 파는 네 가지 — 재시도, 멱등성, 멈춘 실행의 가시성, 실행 중 코드 변경 — 와, 그것이 더하는 두 비용으로 비교합니다 — 결정론 제약(워크플로 코드에 직접 난수·시각 읽기·네트워크 호출 금지 — 액티비티로 이동)과 운영 비용(자체 호스팅 워커 비용 대 Temporal Cloud 액션 단가, 그리고 재생 비용을 키우는 워크플로당 이벤트 히스토리 크기). 같은 표에 둘 대안: Inngest(작은 백엔드에 가벼움), Restate, 그리고 직접 만든 크론 + 상태 테이블 자체. 출처: Temporal — 결정론적 재생을 통한 내구성 실행.

Temporal은 이 카탈로그가 서로 다른 문으로 계속 도착하는 질문에 대한 포장된 답입니다. 패턴은 늘 같습니다 — 프로세스가 실행 중 자신의 죽음을 견디고, 성공한 부분은 다시 하지 않으면서 실패한 부분만 재시도하고, 외부의 무언가를 며칠 기다리고, 운영자가 어디서 멈췄는지 볼 수 있어야 합니다. circuit-breaker-saga는 장애 격리에서, x402-settlement-retry는 결제 재시도에서, irreversible-switch-design은 종료일이 있는 이중 쓰기 전환에서 여기 도달했습니다. 내구성 실행(durable execution)이 셋 다 손으로 짓던 것의 이름입니다.

메커니즘은 한 아이디어 — 결정론적 재생 — 이고, 그것이 곧 전체 비용이기도 합니다. Temporal은 변수를 보존하지 않습니다 — 이벤트의 이력을 보존하고 그 이력에 대해 워크플로 코드를 다시 돌려 상태를 재구성합니다. 워커가 죽어도 있던 자리에서 정확히 재개되는 이유입니다. 그 재생이 옳으려면 워크플로 코드가 결정론적이어야 합니다 — 직접 시각 읽기·난수·네트워크 호출 금지. 이것들은 결과로 기록·재생되는 '액티비티'로 옮겨갑니다. 그 제약은 세부가 아니라 코드 작성 방식을 바꾸고, 도입 전에 플로우를 두 번 모델링할 정직한 이유입니다.

이것은 이 카탈로그가 전에 그린 갈림길을 가진 build-vs-buy 결정입니다. 직접 만든 크론 + 상태 테이블이 바로 그 '대화 2' 선택지입니다 — 작동하고, 작은 백엔드에는 그것이 알맞은 양의 기계일 수 있습니다. Temporal은 플로우가 진짜로 장기 실행·외부 대기일 때 — 정확히 정산 모양일 때 — 그리고 그런 플로우 수가 플로우마다 재시도·가시성을 재구현하는 것이 진짜 비용이 될 만큼 많을 때 무게값을 합니다. build-rent-or-own-the-rail이 결제 레일의 같은 갈림길이고, 이건 실행의 갈림길입니다. 네 이점에 대고 값을 매길 두 비용은 워크플로당 이벤트 히스토리 크기코드에 붙는 결정론 세금입니다.

동작 방식

세 카드가 따로 도착한 패턴

카드 내구성 실행에 도달한 경로
circuit-breaker-saga 장애 격리 / 보상
x402-settlement-retry 결제를 안전하게 재시도
irreversible-switch-design 종료일 있는 이중 쓰기 전환

셋 다 원하는 것 — 크래시 생존, 이중지불 없는 재시도, 외부 상태 대기, 멈춘 위치의 가시성.

결정론적 재생 — 메커니즘과 그 세금

작동 방식 대가
상태 변수 저장이 아니라 이벤트 이력 재생으로 재구성 이벤트 히스토리 크기가 재생 비용을 키움
정확성 결정론적 워크플로 코드 필요 워크플로에 시각/난수/네트워크 금지 — 액티비티로 이동
재개 워커 죽음 → 있던 자리에서 정확히 재개 제약을 받아들이는 이유

Build vs buy

선택지 알맞을 때
직접 만든 크론 + 상태 테이블 작은 백엔드, 적은 플로우
Temporal 장기 실행 + 외부 대기 플로우가 많을 때
Inngest / Restate 더 가벼운 중간 지대

두 비용(히스토리 크기, 결정론 세금)을 네 이점(재시도, 멱등성, 가시성, 실행 중 코드 변경)에 대고 값을 매기세요.

관련 카드

circuit-breaker-saga, x402-settlement-retry, irreversible-switch-design(이것을 원하는 플로우들), build-rent-or-own-the-rail(레일용, 같은 build-vs-buy 갈림길).

← 전체 개발 노트 · 워크스페이스 인덱스 · 맨 위 ↑