내구성 실행(Durable Execution)은 코드가 도는 동안 단계마다 결과를 저장해 두고, 프로세스가 죽어도 처음부터 다시 돌리지 않고 마지막으로 끝낸 단계부터 이어서 실행하는 방식이다. 진행 상황 기록과 재시도를 엔진이 대신 맡아 주기 때문에, 결제나 오래 걸리는 워크플로우, AI 에이전트처럼 중간에 끊기면 안 되는 작업에 쓴다.
| 주문 처리가 재고 차감 직후 멈췄을 때 | 결과 |
|---|---|
| 처음부터 다시 실행 | 결제가 두 번 될 수 있다 |
| 다시 실행하지 않음 | 돈만 받고 배송은 안 된다 |
| 내구성 실행 | 배송 요청부터 이어서 진행 |
순서대로 실행되는 평범한 함수를 쓰고, 외부 API 호출이나 DB 쓰기처럼 바깥에 영향을 주는 부분을 단계(step)로 감싸면 된다. 복구할 때 엔진은 코드를 처음부터 다시 돌리지만, 이미 끝난 단계는 실제로 실행하지 않고 저장해 둔 결과를 꺼내 쓴다. 그래서 지역 변수까지 장애 전과 같은 값으로 돌아온다.
YAML이나 그래프로 흐름을 그려야 했던 기존 워크플로우 엔진과 달리 if문과 반복문을 그대로 쓸 수 있다. 예를 들어 AWS Lambda 내구성 함수는 DurableContext로 부른 작업마다 체크포인트가 자동으로 생긴다.
구현 방식은 크게 둘로 나뉜다. 어느 쪽이든 약속하는 기능은 같고, 운영해야 할 구성 요소 수와 지연 시간이 다르다.
| 방식 | 예 | 특징 |
|---|---|---|
| 외부 오케스트레이터 | Temporal, AWS Step Functions | 별도 서버가 진행 상태를 관리 |
| 라이브러리 | DBOS | 별도 인프라 없이 앱 DB에 상태 저장 |
LangGraph도 같은 개념을 넣어, 그래프 실행 중 상태를 저장하고 사람의 확인을 기다렸다가 멈춘 곳에서 다시 시작한다.
단계를 실행하다 죽으면 그 단계는 다시 실행되므로 보장되는 건 최소 한 번이다. 결제 API처럼 두 번 돌면 안 되는 단계에는 멱등성 키를 붙여 대비해야 한다.
| 주의할 점 | 대응 |
|---|---|
| 같은 단계가 다시 실행될 수 있음 | 멱등성 키로 중복을 막는다 |
| 다시 돌릴 때 결과가 같아야 함 | 현재 시각·난수를 코드에서 직접 쓰지 않는다 |
| 실행 중인 워크플로우가 있을 때 코드 변경 | 배포를 신중하게 계획한다 |
| 체크포인트 저장 비용 | 큰 데이터를 단계 결과로 넘기지 않는다 |
개념 검증 때는 괜찮다가 로직이 복잡해지면서 학습과 디버깅 부담이 커졌다는 현업 후기도 있다.
| 상황 | 단계로 나누는 법 | 얻는 것 |
|---|---|---|
| 결제·주문 처리 | 결제, 재고, 배송, 메일을 각각 단계로 | 중복 결제·누락 없이 끝까지 진행 |
| RAG 문서 수집 | 추출, 청킹, 임베딩, 인덱싱을 단계로 | 임베딩 API가 실패해도 끝난 문서는 건너뜀 |
| 리서치 에이전트 | 모델 응답과 도구 호출을 하나씩 단계로 | 배포가 끼어도 비싼 LLM 응답을 다시 요청하지 않음 |
| 사람 승인 대기 | 승인 대기를 멈춤 지점으로 | 기다리는 동안 서버 비용 없음 (Lambda는 최대 1년) |