From e7521ec96a6380c0f527c4bf60f1fc0bf5ae7ff1 Mon Sep 17 00:00:00 2001 From: Todd Green Date: Thu, 28 May 2026 19:45:10 +0000 Subject: [PATCH 1/3] docs: add a short pg_durable / duroxide-pg disambiguator to README Adds a single-blockquote callout near the top of the README so a reader can immediately tell pg_durable apart from duroxide-pg. Replaces the earlier draft that added a full "Duroxide family" overview here; the overview is now kept only in the duroxide hub README. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f427f0e2..52abcfa2 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ pg_durable brings durable execution to PostgreSQL. Define long-running, fault-tolerant functions entirely in SQL—no external orchestrators, no YAML, no separate deployment. +> **Not to be confused with [duroxide-pg](https://github.com/microsoft/duroxide-pg).** duroxide-pg is the lower-level PostgreSQL provider for the [duroxide](https://github.com/microsoft/duroxide) Rust durable-execution runtime, aimed at developers writing workflows in Rust. pg_durable sits on top of both and exposes durable execution as a SQL-native PostgreSQL extension — reach for it when you want everything inside PG. + ## Features - **Durable** — Function state persists to PostgreSQL. Survives crashes, restarts, and failovers. From 431f704f8ba1faafe83d9989fde3cfd49c9c8858 Mon Sep 17 00:00:00 2001 From: Todd Green Date: Thu, 28 May 2026 22:56:58 +0000 Subject: [PATCH 2/3] Revise text --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 52abcfa2..d4ed46a6 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,6 @@ pg_durable brings durable execution to PostgreSQL. Define long-running, fault-tolerant functions entirely in SQL—no external orchestrators, no YAML, no separate deployment. -> **Not to be confused with [duroxide-pg](https://github.com/microsoft/duroxide-pg).** duroxide-pg is the lower-level PostgreSQL provider for the [duroxide](https://github.com/microsoft/duroxide) Rust durable-execution runtime, aimed at developers writing workflows in Rust. pg_durable sits on top of both and exposes durable execution as a SQL-native PostgreSQL extension — reach for it when you want everything inside PG. - ## Features - **Durable** — Function state persists to PostgreSQL. Survives crashes, restarts, and failovers. @@ -30,6 +28,10 @@ SELECT df.start( 3. **Runtime executes durably** — each step is checkpointed, survives crashes via replay 4. **Query progress** anytime from standard PostgreSQL tables +## Relationship With duroxide-pg +* Use pg_durable when you want pipelines or durable functions directly in SQL and PostgreSQL, no other moving parts needed. +* Use [duroxide-pg](https://github.com/microsoft/duroxide-pg) when you prefer to define functions in Rust, Python, or Node, using PostgreSQL only as a persistent store. + ## Prerequisites - PostgreSQL 17 From ef0c9386efb4e29c03f6c0f9ab33bb4b4e6ca47e Mon Sep 17 00:00:00 2001 From: Todd Green Date: Fri, 29 May 2026 17:10:45 +0000 Subject: [PATCH 3/3] docs: rework Architecture section to show duroxide/duroxide-pg layering The previous Architecture diagram glossed over duroxide-pg entirely and mislabelled the durable runtime tables as 'duroxide internals' inside the df schema. Update the section to: - Name duroxide (orchestration runtime) and duroxide-pg (PostgreSQL state provider) explicitly and describe what each contributes. - Replace the diagram with a precisely-aligned nested view showing pg_durable -> duroxide -> duroxide-pg -> PostgreSQL, plus the actual schemas (df.* for DSL graphs, duroxide.* for runtime state). - Fold the 'which to pick' guidance (formerly its own 'Relationship With duroxide-pg' section) into the Architecture section as a trailing note, framed correctly: pg_durable is built on top of duroxide and duroxide-pg, not an alternative to them. Also fix two stale items in the old diagram: 'durable.if()' -> 'df.if()' and dropping the misleading '(duroxide internals)' label on the df schema. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- README.md | 52 +++++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index d4ed46a6..4085815c 100644 --- a/README.md +++ b/README.md @@ -28,10 +28,6 @@ SELECT df.start( 3. **Runtime executes durably** — each step is checkpointed, survives crashes via replay 4. **Query progress** anytime from standard PostgreSQL tables -## Relationship With duroxide-pg -* Use pg_durable when you want pipelines or durable functions directly in SQL and PostgreSQL, no other moving parts needed. -* Use [duroxide-pg](https://github.com/microsoft/duroxide-pg) when you prefer to define functions in Rust, Python, or Node, using PostgreSQL only as a persistent store. - ## Prerequisites - PostgreSQL 17 @@ -160,32 +156,38 @@ See [tests/e2e/](tests/e2e/) for details. ## Architecture -pg_durable consists of: - -1. **SQL DSL Layer** — Operators that build function graphs -2. **Duroxide Runtime** — Background worker that executes functions durably -3. **PostgreSQL Tables** — Store function definitions, state, and history +pg_durable is a PostgreSQL extension (built with [pgrx](https://github.com/pgcentralfoundation/pgrx)) — everything runs inside the PostgreSQL server, no external services. The extension exposes a SQL DSL for building function graphs and registers a background worker that executes them durably on top of two lower-level Rust libraries: -The runtime is powered by [duroxide](https://github.com/microsoft/duroxide), a durable task framework for Rust. +- [duroxide](https://github.com/microsoft/duroxide) — a durable task framework providing the orchestration runtime (deterministic replay, checkpoints, sub-orchestrations, timers). +- [duroxide-pg](https://github.com/microsoft/duroxide-pg) — a PostgreSQL-backed state provider for duroxide. It persists runtime state (instances, history, work queues) in a dedicated `duroxide.*` schema owned by the extension. ``` -┌────────────────────────────────────────────────────────────────┐ -│ PostgreSQL │ -│ ┌──────────────────────────────────────────────────────────┐ │ -│ │ pg_durable Extension (pgrx) │ │ -│ │ │ │ -│ │ DSL: 'sql' |=> 'name' ~> 'sql2' │ │ -│ │ Functions: durable.if() | durable.join() | durable.loop() │ -│ │ │ │ -│ │ Duroxide Runtime (background worker) │ │ -│ │ • Polls for work, executes functions, checkpoints │ │ -│ │ │ │ -│ └──────────────────────────────────────────────────────────┘ │ -│ │ -│ df schema: nodes | instances | (duroxide internals) │ -└────────────────────────────────────────────────────────────────┘ +┌────────────────────────────────────────────────────────────────────┐ +│ PostgreSQL │ +│ │ +│ ┌──────────────────────────────────────────────────────────────┐ │ +│ │ pg_durable extension (pgrx) │ │ +│ │ │ │ +│ │ SQL DSL 'sql' |=> 'name' ~> 'sql2' │ │ +│ │ df.if() | df.join() | df.loop() │ │ +│ │ │ │ +│ │ Background worker (hosts the duroxide runtime in-process) │ │ +│ │ ┌────────────────────────────────────────────────────────┐ │ │ +│ │ │ duroxide (orchestration runtime) │ │ │ +│ │ │ ┌──────────────────────────────────────────────────┐ │ │ │ +│ │ │ │ duroxide-pg (PostgreSQL state provider) │ │ │ │ +│ │ │ └──────────────────────────────────────────────────┘ │ │ │ +│ │ └────────────────────────────────────────────────────────┘ │ │ +│ └──────────────────────────────────────────────────────────────┘ │ +│ │ +│ Schemas │ +│ df.* DSL graphs (nodes, instances, vars) │ +│ duroxide.* runtime state (owned by duroxide-pg) │ +└────────────────────────────────────────────────────────────────────┘ ``` +If you'd rather author durable workflows in Rust, Python, or Node while still persisting state in PostgreSQL, you can use duroxide and duroxide-pg directly from your host language — pg_durable is what you'd build on top of that pair when you'd prefer authoring in SQL. + ## Status 🚧 **Early Development** — Not yet ready for production use.