Skip to content

pg_durable

Durable SQL functions for PostgreSQL

pg_durable : Durable SQL functions for PostgreSQL

Overview

ID Extension Package Version Category License Language
2870 pg_durable pg_durable 0.2.8 FEAT PostgreSQL Rust
Attribute Has Binary Has Library Need Load Has DDL Relocatable Trusted
--sLd-- No Yes Yes Yes no no
Relationships
Schemas pg_catalog df _duroxide
See Also pg_task pgmq pg_background ulak pgmb pg_later pg_dispatch pg_retry fsm_core pglock
Requires preload and a superuser worker role; pgrx 0.19.2.

Packages

Type Repo Version PG Major Compatibility Package Pattern Dependencies
EXT PIGSTY 0.2.8 18 17 16 15 14 pg_durable -
RPM PIGSTY 0.2.8 18 17 16 15 14 pg_durable_$v -
DEB PIGSTY 0.2.8 18 17 16 15 14 postgresql-$v-pg-durable -
Linux / PG PG18 PG17 PG16 PG15 PG14
el8.x86_64 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8
el8.aarch64 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8
el9.x86_64 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8
el9.aarch64 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8
el10.x86_64 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8
el10.aarch64 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8
d12.x86_64 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8
d12.aarch64 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8
d13.x86_64 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8
d13.aarch64 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8
u22.x86_64 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8
u22.aarch64 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8
u24.x86_64 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8
u24.aarch64 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8
u26.x86_64 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8
u26.aarch64 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8 PIGSTY 0.2.8
Package Version OS ORG SIZE File URL
pg_durable_18 0.2.8 el8.x86_64 pigsty 5.1 MiB pg_durable_18-0.2.8-1PGSTY.el8.x86_64.rpm
pg_durable_18 0.2.8 el8.aarch64 pigsty 4.1 MiB pg_durable_18-0.2.8-1PGSTY.el8.aarch64.rpm
pg_durable_18 0.2.8 el9.x86_64 pigsty 5.0 MiB pg_durable_18-0.2.8-1PGSTY.el9.x86_64.rpm
pg_durable_18 0.2.8 el9.aarch64 pigsty 4.3 MiB pg_durable_18-0.2.8-1PGSTY.el9.aarch64.rpm
pg_durable_18 0.2.8 el10.x86_64 pigsty 5.0 MiB pg_durable_18-0.2.8-1PGSTY.el10.x86_64.rpm
pg_durable_18 0.2.8 el10.aarch64 pigsty 4.3 MiB pg_durable_18-0.2.8-1PGSTY.el10.aarch64.rpm
postgresql-18-pg-durable 0.2.8 d12.x86_64 pigsty 4.2 MiB postgresql-18-pg-durable_0.2.8-1PGSTY~bookworm_amd64.deb
postgresql-18-pg-durable 0.2.8 d12.aarch64 pigsty 3.3 MiB postgresql-18-pg-durable_0.2.8-1PGSTY~bookworm_arm64.deb
postgresql-18-pg-durable 0.2.8 d13.x86_64 pigsty 4.2 MiB postgresql-18-pg-durable_0.2.8-1PGSTY~trixie_amd64.deb
postgresql-18-pg-durable 0.2.8 d13.aarch64 pigsty 3.3 MiB postgresql-18-pg-durable_0.2.8-1PGSTY~trixie_arm64.deb
postgresql-18-pg-durable 0.2.8 u22.x86_64 pigsty 4.6 MiB postgresql-18-pg-durable_0.2.8-1PGSTY~jammy_amd64.deb
postgresql-18-pg-durable 0.2.8 u22.aarch64 pigsty 3.9 MiB postgresql-18-pg-durable_0.2.8-1PGSTY~jammy_arm64.deb
postgresql-18-pg-durable 0.2.8 u24.x86_64 pigsty 4.6 MiB postgresql-18-pg-durable_0.2.8-1PGSTY~noble_amd64.deb
postgresql-18-pg-durable 0.2.8 u24.aarch64 pigsty 3.9 MiB postgresql-18-pg-durable_0.2.8-1PGSTY~noble_arm64.deb
postgresql-18-pg-durable 0.2.8 u26.x86_64 pigsty 4.6 MiB postgresql-18-pg-durable_0.2.8-1PGSTY~resolute_amd64.deb
postgresql-18-pg-durable 0.2.8 u26.aarch64 pigsty 3.9 MiB postgresql-18-pg-durable_0.2.8-1PGSTY~resolute_arm64.deb
Package Version OS ORG SIZE File URL
pg_durable_17 0.2.8 el8.x86_64 pigsty 5.1 MiB pg_durable_17-0.2.8-1PGSTY.el8.x86_64.rpm
pg_durable_17 0.2.8 el8.aarch64 pigsty 4.0 MiB pg_durable_17-0.2.8-1PGSTY.el8.aarch64.rpm
pg_durable_17 0.2.8 el9.x86_64 pigsty 5.0 MiB pg_durable_17-0.2.8-1PGSTY.el9.x86_64.rpm
pg_durable_17 0.2.8 el9.aarch64 pigsty 4.3 MiB pg_durable_17-0.2.8-1PGSTY.el9.aarch64.rpm
pg_durable_17 0.2.8 el10.x86_64 pigsty 5.0 MiB pg_durable_17-0.2.8-1PGSTY.el10.x86_64.rpm
pg_durable_17 0.2.8 el10.aarch64 pigsty 4.3 MiB pg_durable_17-0.2.8-1PGSTY.el10.aarch64.rpm
postgresql-17-pg-durable 0.2.8 d12.x86_64 pigsty 4.2 MiB postgresql-17-pg-durable_0.2.8-1PGSTY~bookworm_amd64.deb
postgresql-17-pg-durable 0.2.8 d12.aarch64 pigsty 3.3 MiB postgresql-17-pg-durable_0.2.8-1PGSTY~bookworm_arm64.deb
postgresql-17-pg-durable 0.2.8 d13.x86_64 pigsty 4.2 MiB postgresql-17-pg-durable_0.2.8-1PGSTY~trixie_amd64.deb
postgresql-17-pg-durable 0.2.8 d13.aarch64 pigsty 3.3 MiB postgresql-17-pg-durable_0.2.8-1PGSTY~trixie_arm64.deb
postgresql-17-pg-durable 0.2.8 u22.x86_64 pigsty 4.6 MiB postgresql-17-pg-durable_0.2.8-1PGSTY~jammy_amd64.deb
postgresql-17-pg-durable 0.2.8 u22.aarch64 pigsty 3.9 MiB postgresql-17-pg-durable_0.2.8-1PGSTY~jammy_arm64.deb
postgresql-17-pg-durable 0.2.8 u24.x86_64 pigsty 4.6 MiB postgresql-17-pg-durable_0.2.8-1PGSTY~noble_amd64.deb
postgresql-17-pg-durable 0.2.8 u24.aarch64 pigsty 3.9 MiB postgresql-17-pg-durable_0.2.8-1PGSTY~noble_arm64.deb
postgresql-17-pg-durable 0.2.8 u26.x86_64 pigsty 4.6 MiB postgresql-17-pg-durable_0.2.8-1PGSTY~resolute_amd64.deb
postgresql-17-pg-durable 0.2.8 u26.aarch64 pigsty 3.9 MiB postgresql-17-pg-durable_0.2.8-1PGSTY~resolute_arm64.deb
Package Version OS ORG SIZE File URL
pg_durable_16 0.2.8 el8.x86_64 pigsty 5.1 MiB pg_durable_16-0.2.8-1PGSTY.el8.x86_64.rpm
pg_durable_16 0.2.8 el8.aarch64 pigsty 4.0 MiB pg_durable_16-0.2.8-1PGSTY.el8.aarch64.rpm
pg_durable_16 0.2.8 el9.x86_64 pigsty 5.0 MiB pg_durable_16-0.2.8-1PGSTY.el9.x86_64.rpm
pg_durable_16 0.2.8 el9.aarch64 pigsty 4.3 MiB pg_durable_16-0.2.8-1PGSTY.el9.aarch64.rpm
pg_durable_16 0.2.8 el10.x86_64 pigsty 5.0 MiB pg_durable_16-0.2.8-1PGSTY.el10.x86_64.rpm
pg_durable_16 0.2.8 el10.aarch64 pigsty 4.3 MiB pg_durable_16-0.2.8-1PGSTY.el10.aarch64.rpm
postgresql-16-pg-durable 0.2.8 d12.x86_64 pigsty 4.2 MiB postgresql-16-pg-durable_0.2.8-1PGSTY~bookworm_amd64.deb
postgresql-16-pg-durable 0.2.8 d12.aarch64 pigsty 3.3 MiB postgresql-16-pg-durable_0.2.8-1PGSTY~bookworm_arm64.deb
postgresql-16-pg-durable 0.2.8 d13.x86_64 pigsty 4.2 MiB postgresql-16-pg-durable_0.2.8-1PGSTY~trixie_amd64.deb
postgresql-16-pg-durable 0.2.8 d13.aarch64 pigsty 3.3 MiB postgresql-16-pg-durable_0.2.8-1PGSTY~trixie_arm64.deb
postgresql-16-pg-durable 0.2.8 u22.x86_64 pigsty 4.6 MiB postgresql-16-pg-durable_0.2.8-1PGSTY~jammy_amd64.deb
postgresql-16-pg-durable 0.2.8 u22.aarch64 pigsty 3.9 MiB postgresql-16-pg-durable_0.2.8-1PGSTY~jammy_arm64.deb
postgresql-16-pg-durable 0.2.8 u24.x86_64 pigsty 4.6 MiB postgresql-16-pg-durable_0.2.8-1PGSTY~noble_amd64.deb
postgresql-16-pg-durable 0.2.8 u24.aarch64 pigsty 3.9 MiB postgresql-16-pg-durable_0.2.8-1PGSTY~noble_arm64.deb
postgresql-16-pg-durable 0.2.8 u26.x86_64 pigsty 4.6 MiB postgresql-16-pg-durable_0.2.8-1PGSTY~resolute_amd64.deb
postgresql-16-pg-durable 0.2.8 u26.aarch64 pigsty 3.9 MiB postgresql-16-pg-durable_0.2.8-1PGSTY~resolute_arm64.deb
Package Version OS ORG SIZE File URL
pg_durable_15 0.2.8 el8.x86_64 pigsty 5.1 MiB pg_durable_15-0.2.8-1PGSTY.el8.x86_64.rpm
pg_durable_15 0.2.8 el8.aarch64 pigsty 4.0 MiB pg_durable_15-0.2.8-1PGSTY.el8.aarch64.rpm
pg_durable_15 0.2.8 el9.x86_64 pigsty 5.0 MiB pg_durable_15-0.2.8-1PGSTY.el9.x86_64.rpm
pg_durable_15 0.2.8 el9.aarch64 pigsty 4.2 MiB pg_durable_15-0.2.8-1PGSTY.el9.aarch64.rpm
pg_durable_15 0.2.8 el10.x86_64 pigsty 5.0 MiB pg_durable_15-0.2.8-1PGSTY.el10.x86_64.rpm
pg_durable_15 0.2.8 el10.aarch64 pigsty 4.3 MiB pg_durable_15-0.2.8-1PGSTY.el10.aarch64.rpm
postgresql-15-pg-durable 0.2.8 d12.x86_64 pigsty 4.2 MiB postgresql-15-pg-durable_0.2.8-1PGSTY~bookworm_amd64.deb
postgresql-15-pg-durable 0.2.8 d12.aarch64 pigsty 3.3 MiB postgresql-15-pg-durable_0.2.8-1PGSTY~bookworm_arm64.deb
postgresql-15-pg-durable 0.2.8 d13.x86_64 pigsty 4.2 MiB postgresql-15-pg-durable_0.2.8-1PGSTY~trixie_amd64.deb
postgresql-15-pg-durable 0.2.8 d13.aarch64 pigsty 3.3 MiB postgresql-15-pg-durable_0.2.8-1PGSTY~trixie_arm64.deb
postgresql-15-pg-durable 0.2.8 u22.x86_64 pigsty 4.6 MiB postgresql-15-pg-durable_0.2.8-1PGSTY~jammy_amd64.deb
postgresql-15-pg-durable 0.2.8 u22.aarch64 pigsty 3.9 MiB postgresql-15-pg-durable_0.2.8-1PGSTY~jammy_arm64.deb
postgresql-15-pg-durable 0.2.8 u24.x86_64 pigsty 4.6 MiB postgresql-15-pg-durable_0.2.8-1PGSTY~noble_amd64.deb
postgresql-15-pg-durable 0.2.8 u24.aarch64 pigsty 3.9 MiB postgresql-15-pg-durable_0.2.8-1PGSTY~noble_arm64.deb
postgresql-15-pg-durable 0.2.8 u26.x86_64 pigsty 4.6 MiB postgresql-15-pg-durable_0.2.8-1PGSTY~resolute_amd64.deb
postgresql-15-pg-durable 0.2.8 u26.aarch64 pigsty 3.9 MiB postgresql-15-pg-durable_0.2.8-1PGSTY~resolute_arm64.deb
Package Version OS ORG SIZE File URL
pg_durable_14 0.2.8 el8.x86_64 pigsty 5.1 MiB pg_durable_14-0.2.8-1PGSTY.el8.x86_64.rpm
pg_durable_14 0.2.8 el8.aarch64 pigsty 4.0 MiB pg_durable_14-0.2.8-1PGSTY.el8.aarch64.rpm
pg_durable_14 0.2.8 el9.x86_64 pigsty 5.0 MiB pg_durable_14-0.2.8-1PGSTY.el9.x86_64.rpm
pg_durable_14 0.2.8 el9.aarch64 pigsty 4.2 MiB pg_durable_14-0.2.8-1PGSTY.el9.aarch64.rpm
pg_durable_14 0.2.8 el10.x86_64 pigsty 5.0 MiB pg_durable_14-0.2.8-1PGSTY.el10.x86_64.rpm
pg_durable_14 0.2.8 el10.aarch64 pigsty 4.3 MiB pg_durable_14-0.2.8-1PGSTY.el10.aarch64.rpm
postgresql-14-pg-durable 0.2.8 d12.x86_64 pigsty 4.2 MiB postgresql-14-pg-durable_0.2.8-1PGSTY~bookworm_amd64.deb
postgresql-14-pg-durable 0.2.8 d12.aarch64 pigsty 3.3 MiB postgresql-14-pg-durable_0.2.8-1PGSTY~bookworm_arm64.deb
postgresql-14-pg-durable 0.2.8 d13.x86_64 pigsty 4.2 MiB postgresql-14-pg-durable_0.2.8-1PGSTY~trixie_amd64.deb
postgresql-14-pg-durable 0.2.8 d13.aarch64 pigsty 3.3 MiB postgresql-14-pg-durable_0.2.8-1PGSTY~trixie_arm64.deb
postgresql-14-pg-durable 0.2.8 u22.x86_64 pigsty 4.6 MiB postgresql-14-pg-durable_0.2.8-1PGSTY~jammy_amd64.deb
postgresql-14-pg-durable 0.2.8 u22.aarch64 pigsty 3.9 MiB postgresql-14-pg-durable_0.2.8-1PGSTY~jammy_arm64.deb
postgresql-14-pg-durable 0.2.8 u24.x86_64 pigsty 4.6 MiB postgresql-14-pg-durable_0.2.8-1PGSTY~noble_amd64.deb
postgresql-14-pg-durable 0.2.8 u24.aarch64 pigsty 3.9 MiB postgresql-14-pg-durable_0.2.8-1PGSTY~noble_arm64.deb
postgresql-14-pg-durable 0.2.8 u26.x86_64 pigsty 4.6 MiB postgresql-14-pg-durable_0.2.8-1PGSTY~resolute_amd64.deb
postgresql-14-pg-durable 0.2.8 u26.aarch64 pigsty 3.8 MiB postgresql-14-pg-durable_0.2.8-1PGSTY~resolute_arm64.deb

Source

pig build pkg pg_durable;		# build rpm/deb

Install

Make sure PGDG and PIGSTY repo available:

pig repo add pgsql -u   # add both repo and update cache

Install this extension with pig:

pig install pg_durable;		# install via package name, for the active PG version

pig install pg_durable -v 18;   # install for PG 18
pig install pg_durable -v 17;   # install for PG 17
pig install pg_durable -v 16;   # install for PG 16
pig install pg_durable -v 15;   # install for PG 15
pig install pg_durable -v 14;   # install for PG 14

Config this extension to shared_preload_libraries:

shared_preload_libraries = 'pg_durable';

Create this extension with:

CREATE EXTENSION pg_durable;

Usage

Sources:

pg_durable runs durable, fault-tolerant SQL workflows inside PostgreSQL. A workflow is a graph of SQL steps, timers, signals, conditions, and parallel branches submitted with df.start(). Execution state is checkpointed in PostgreSQL so completed steps are not repeated after a crash, restart, or retry.

Enable and Grant Access

Preload the worker, select its database and superuser role if the defaults are unsuitable, then restart PostgreSQL:

shared_preload_libraries = 'pg_durable'
pg_durable.database = 'postgres'
pg_durable.worker_role = 'postgres'

Create the extension in pg_durable.database and grant an application login role access:

CREATE EXTENSION pg_durable;
SELECT df.grant_usage('app_role');

The worker role must be a superuser because it manages all users’ instances while bypassing row-level security. The role that calls df.start() must have LOGIN, because workflow SQL is executed through a connection authenticated as that captured role.

Build and Run a Workflow

SELECT df.start(
    'SELECT 100 AS amount' |=> 'total'
    ~> 'SELECT $total.amount * 2 AS doubled',
    'double-total'
);

df.start() returns an instance ID. Use it to monitor or control the run:

SELECT df.status('a1b2c3d4');
SELECT df.result('a1b2c3d4');
SELECT * FROM df.instance_nodes('a1b2c3d4');
SELECT * FROM df.instance_executions('a1b2c3d4', 20);
SELECT df.cancel('a1b2c3d4', 'No longer needed');

DSL Index

  • ~> sequences steps; |=> names a result for $name, $name.column, or $name.* substitution.
  • & / df.join() waits for parallel branches; | / df.race() keeps the first result.
  • ?> and !> / df.if() select conditional branches; @> / df.loop() repeats a graph.
  • df.sleep(), df.wait_for_schedule(), and df.wait_for_signal() make waits durable.
  • df.signal(), df.wait_for_completion(), df.explain(), and the instance-inspection functions operate on running or stored instances.
  • df.setvar(), df.getvar(), df.unsetvar(), and df.clearvars() manage per-user variables captured when df.start() is called.

Version 0.2.6 Boundaries

  • Upstream source installation and published images support PostgreSQL 17 and 18 with pgrx 0.16.1. The extension still requires shared_preload_libraries, a restart, and a superuser worker role.
  • Upgrades through 0.2.4 and 0.2.5 contain replay-breaking workflow changes. Drain or cancel in-flight JOIN, RACE, loop, and df.wait_for_schedule() work before upgrading; the 0.2.4 df.nodes key migration also takes an ACCESS EXCLUSIVE lock.
  • df.start(..., transaction_mode => 'new') persists an independent start outside the caller transaction. Cluster-wide admission defaults to two concurrent starts and is controlled by pg_durable.max_new_transaction_starts and pg_durable.new_transaction_start_timeout.
  • Variable substitution is resolved once from left to right in 0.2.6, so token-shaped text introduced by a value is not rescanned. It remains raw SQL substitution; never place untrusted input in {name} variables. Named step-result substitution through $name performs SQL escaping.
  • The undocumented df.ensure_durofut(text) helper was removed. Drop or rewrite customer-owned dependent objects before upgrading.
  • Re-run df.grant_usage() after ALTER EXTENSION ... UPDATE, because grants on all functions do not automatically include functions added later.
  • df.http() and df.http_multipart() availability and egress policy are compile-time features. Their restrictions do not sandbox arbitrary SQL or other installed extensions.
  • The project remains pre-1.0, and upstream’s published Docker images are for evaluation and learning rather than production. Read every adjacent upgrade warning instead of assuming an untested multi-version jump is replay-safe.