Introducing Durable Functions in PostgreSQL (pg_durable)
Author: Abe Omorogbe, Pino De Candia, TJ Green (Microsoft) | Source: Microsoft Community Hub | Published: 2026-06-10
한 줄 요약
Postgres에 없던 프리미티브 — 데이터가 있는 곳에서 도는 durable·비동기 백그라운드 작업 — 을 background worker + DSL 확장으로 채워, 외부 오케스트레이터 없이 재시도·병렬·스케줄·크래시 복구가 되는 워크플로를 SQL로 정의한다.
핵심 주장/내용
- 두 가지 회피 경로 모두 워크어라운드: ① PL/pgSQL 함수 하나에 워크플로를 우겨넣기 → 커넥션 점유, 하나의 거대 트랜잭션, 긴 락, 부분 진행 가시성 없음, 연결 끊기면 전부 유실 ② 외부 서비스로 빼기 → 잡 큐·폴링 워커·상태 테이블·재시도·크래시 복구 sweep까지 분산 시스템을 새로 운영
- pg_durable 구조: DSL + duroxide 런타임을 Postgres background worker에서 호스팅.
df.start(...)가 즉시 instance ID를 반환하고 작업은 옆에서 실행 → 커넥션·트랜잭션을 막지 않음.df.status()/df.result()로 조회 - 비동기이므로 자동으로 step 분할: 각 step이 자기 세션·트랜잭션에서 실행되고 진행분을 커밋 후 다음으로 넘김. step은 Postgres에 체크포인트되고 deterministic replay로 복구 → 크래시·재시작·페일오버를 넘어 중단 지점부터 재개. 실패한 step만 재시도
- 실행 상태가 DB에 살기 때문에 DB의 durability·HA·백업·PITR을 그대로 상속. 워크플로 정의 자체는 DB에 없어도 되며 애플리케이션이 일반 커넥션으로 전송 가능
- HorizonDB의 AI pipelines: pg_durable이 durable 실행 엔진,
ai.*API가 source/steps/sink/trigger 모델을 제공해 durable 그래프로 컴파일.ai.chunk→ai.embed각 단계가 durable 노드라 embed 실패 시 chunk를 재실행하지 않음.trigger => 'on_change'로 변경분만 임베딩 - 적용 경계: 워크플로의 무게중심이 Postgres 상태에 밀착해 있으면(임베딩 파이프라인, ETL, 스케줄 유지보수, 큐형 백그라운드 잡) pg_durable. 이기종 서비스로 팬아웃하거나 SQL step에 매핑되지 않는 임의 앱 로직이면 Temporal/Airflow 같은 전용 오케스트레이터
주요 수치 / 사실
- DSL 연산자:
~>순차,&병렬(전부 대기),|레이스(먼저 끝난 것),?>/!>조건,@>durable 루프,|=>결과를 변수로 캡처 - 함수:
df.if(),df.loop(),df.join(),df.http()(allowlist 엔드포인트),df.wait_for_schedule()(cron),df.wait_for_signal()(외부 이벤트 대기 = human-in-the-loop) - 손으로 만들면 300줄+ (큐 테이블, 폴링 워커, 상태머신 row, step별 재시도, 복구 sweep) 짜리를 SQL 표현식 몇 줄로 대체
- PostgreSQL License 오픈소스, Postgres 17 이상. 출시 며칠 만에 GitHub 1.7K stars, HN 상위
관련 위키
Source: 원문 보기