Workflow SDK와 Nitro v3: 장기 실행 백엔드가 앱 런타임 안으로 들어온다

테크

백엔드 개발에서 가장 피곤한 코드는 보통 “한 번에 끝나지 않는 일” 주변에 생긴다. 회원가입 후 환영 이메일을 보내고 며칠 뒤 온보딩을 이어가야 한다. 결제는 성공했지만 확인 응답을 잃어버릴 수 있다. AI 에이전트는 사용자의 승인을 기다렸다가 다시 도구를 호출해야 한다. 이런 흐름은 HTTP 요청 하나로 끝나지 않고, 큐·스케줄러·상태 테이블·재시도 정책·관측성 화면을 끌어들인다.

Vercel이 2026년 6월 13일 공개한 “Workflow SDK now runs natively in Nitro v3” 업데이트는 이 복잡도를 Nitro/Nuxt 계열 앱 안으로 더 가까이 가져온다. 발표의 핵심은 Workflow SDK의 Nitro v3 통합이 베타가 되었고, step이 앱과 분리된 별도 번들이 아니라 같은 bundled runtime 안에서 실행된다는 점이다. 그 결과 Nitro의 `useStorage()` 같은 server-side API를 `"use step"` 함수 안에서 직접 사용할 수 있다.

이 글은 “새 SDK가 나왔다”는 뉴스가 아니다. Nitro를 서버 런타임으로 쓰는 팀이 장기 실행 작업을 어디에 둘지, 어떤 side effect를 어떻게 안전하게 재시도할지, 배포 중 실행 중인 workflow를 어떻게 다룰지 결정하기 위한 실무 플레이북이다.

Nitro v3 앱 런타임 안에서 API route가 Workflow SDK를 시작하고 use workflow orchestrator, use step 함수, Nitro storage, retry, idempotency, observability로 이어지는 아키텍처 다이어그램
Nitro v3 네이티브 통합은 워크플로 step을 별도 번들 바깥의 작업자가 아니라 앱과 같은 런타임 안에서 다루게 만든다.

무슨 일이 있었나

Vercel Changelog에 따르면 Workflow SDK의 Nitro v3 네이티브 통합은 현재 베타이며, workflow route는 Nitro 앱 빌드의 일부로 묶인다. 문서는 dependencies가 trace되고 사용하지 않는 코드는 tree-shaking되어 실행에 필요한 출력만 포함된다고 설명한다. 개발 서버에서는 `/_workflow` 경로로 workflow Web UI를 열어 run을 inspect, monitor, debug할 수 있다는 점도 함께 공개됐다.

Workflow SDK의 Nitro 문서는 `workflow/nitro` 모듈을 `nitro.config.ts`에 추가하면 `"use workflow"`와 `"use step"` directive를 사용할 수 있다고 안내한다. 예시는 `start(handleUserSignup, [email])`로 API route에서 workflow를 비동기 시작하고, workflow 내부에서 `sleep("5s")`로 compute를 붙잡지 않은 채 중단 후 재개하는 흐름을 보여준다. 배포 섹션은 Vercel에서 Fluid compute를 켜면 resume 때의 cold start 비용을 줄이는 데 유리하다고 설명한다.

왜 중요한가

이번 변화가 중요한 이유는 Nitro가 이미 “어디에나 배포 가능한 서버 런타임”을 지향하기 때문이다. Nitro v3 홈페이지는 Vite 애플리케이션에 production-ready server를 붙이고, Node.js, Cloudflare Workers, Deno, Bun, AWS Lambda, Vercel, Netlify 등 여러 target에 배포할 수 있다고 설명한다. 여기에 durable workflow가 네이티브로 붙으면 Nuxt/Nitro 팀은 장기 실행 백엔드를 별도 worker 프로젝트로 떼기 전에 앱 런타임 안에서 먼저 설계할 수 있다.

실무적으로는 경계가 바뀐다. 예전에는 “이건 큐 worker로 빼야 한다”는 판단이 빠르게 나왔다. 이제는 API route가 workflow를 시작하고, workflow가 step을 durable하게 실행하며, step이 Nitro storage나 서버 API를 직접 호출하는 구조가 가능해진다. 이는 코드 위치를 단순화하지만, 동시에 재시도·idempotency·versioning·관측성을 앱 코드의 일급 설계 항목으로 올린다.

커뮤니티 신호

개발자 커뮤니티의 관심은 오래전부터 “durable execution을 async/await처럼 쓸 수 있느냐”에 모여 있었다. Hacker News의 durable TypeScript function 논의에서는 checkpoint, generator restart, durable promise 같은 구현 모델이 반복적으로 언급됐다. 이것은 공식 사실의 근거가 아니라, 개발자가 원하는 추상화가 큐 설정 파일보다 코드 흐름에 가깝다는 신호다.

반대로 Vercel Community에는 Workflow testing을 어떻게 해야 하는지 묻는 글도 있었다. 이 역시 제품 기능을 검증하는 출처가 아니라 운영 감각을 보여주는 신호로 읽어야 한다. durable workflow는 “코드가 예쁘다”만으로 충분하지 않다. 테스트, 재시도, 로컬 관측성, 배포 버전 경계가 명확하지 않으면 팀은 기존 큐보다 더 낯선 문제를 얻게 된다.

개발·운영 영향

개발 영향은 우선 파일 구조에서 나타난다. Nitro 앱의 route handler가 workflow를 시작하고, `workflows/` 디렉터리의 함수가 orchestration을 맡고, 개별 step이 비즈니스 side effect를 수행한다. step이 앱과 같은 runtime 안에 있으므로 storage, config, server API 접근이 자연스러워진다. 대신 step 입력은 직렬화 가능해야 하고, retry가 발생해도 안전하도록 외부 API 호출을 설계해야 한다.

운영 영향은 더 중요하다. Workflow SDK 문서는 step 내부 오류가 기본적으로 retry되고, `maxRetries`, `FatalError`, `RetryableError`, `retryAfter`로 동작을 조정할 수 있다고 설명한다. Idempotency 문서는 재시도되는 결제·이메일·SMS·큐 발행에는 `stepId`처럼 stable한 idempotency key를 쓰라고 안내한다. Versioning 문서는 workflow run이 시작된 deployment에 고정되며, 실행 중인 run을 새 코드로 옮기려면 취소 후 최신 deployment에서 재실행하는 식의 명시적 절차가 필요하다고 설명한다.

즉 Nitro 네이티브 통합은 “백그라운드 작업을 쉽게 만들었다”가 아니라 “장기 실행 작업의 운영 규칙을 앱 코드 가까이에 놓았다”에 가깝다. 개발팀은 이제 queue worker를 따로 운영하지 않아도 되는 장점과, workflow 코드가 배포·재시도·관측성과 직접 연결되는 책임을 함께 받아들여야 한다.

팀이 바로 점검할 체크리스트

워크플로 후보를 HTTP 요청 안에서 끝내야 하는 작업, 큐가 필요한 작업, 사람이 개입하는 작업으로 나눈다.

`"use workflow"` 함수와 `"use step"` 함수의 입력·출력 타입을 배포 간에 깨지지 않게 유지한다.

결제, 이메일, 외부 API 쓰기, 큐 발행 같은 side effect에는 stable stepId 기반 idempotency key를 붙인다.

무작정 재시도하면 안 되는 4xx·검증 실패는 FatalError로 분리하고, 429·일시 장애는 RetryableError와 retryAfter로 다룬다.

배포 후 실행 중인 run이 어떤 deployment에 고정되는지 운영 runbook에 적고, 수정 후 재실행 절차를 만든다.

Nitro의 useStorage, server API, route handler를 step 내부에서 직접 쓰는 경우 local/prod storage backend 차이를 테스트한다.

관측성 UI와 CLI에서 runId, stepId, input class, retry count, 실패 코드, 비용이 추적되는지 확인한다.

리스크와 반론

반론도 분명하다. 모든 백엔드 작업을 durable workflow로 바꿀 필요는 없다. 짧은 캐시 갱신, 단순 webhook forwarding, 한 번 실패하면 사용자가 다시 누르면 되는 작업은 기존 request/response나 작은 queue가 더 단순할 수 있다. 또 Nitro 통합이 베타라는 점도 중요하다. production-critical 결제, 재고, 법적 알림 흐름에 바로 적용하려면 문서화된 한계, 배포 target, 관측성, rollback 절차를 먼저 검증해야 한다.

또 하나의 리스크는 “같은 런타임”이라는 편의가 경계 흐림으로 이어지는 것이다. step 안에서 앱 내부 helper를 마음껏 호출하면 처음에는 빠르지만, 나중에는 retry 가능한 코드와 retry하면 안 되는 코드가 섞일 수 있다. durable workflow는 side effect를 명확히 나누고 idempotency key를 붙였을 때 강하다. 그렇지 않으면 같은 이메일을 여러 번 보내거나, 이미 완료된 외부 API 쓰기를 다시 실행하는 위험이 남는다.

실무 결론은 보수적이다. Nitro v3와 Workflow SDK를 쓰는 팀은 먼저 onboarding email, report generation, AI agent approval flow, delayed notification처럼 실패해도 되돌리기 쉽고 관측 가능한 흐름부터 시작하는 것이 좋다. 결제·재고·계정 삭제처럼 되돌리기 어려운 흐름은 rollback step, idempotency, versioning runbook을 갖춘 뒤에 옮겨야 한다.

출처