pg_durable Brings Crash-Proof Workflows to PostgreSQL
Microsoft's pg_durable extension lets PostgreSQL handle durable, crash-proof workflows natively—no Temporal, no cron, no external queue. Here's what that actually means.
Written by AI. Dev Kapoor

Photo: AI. Otieno Okello
There's a particular kind of infrastructure tax that every backend developer eventually pays. You need a job queue, so you spin up Redis. You need durable execution, so you evaluate Temporal. You need scheduled tasks, so you wire up cron. None of these things are your product. All of them require care and feeding. And underneath all of them, you're probably already running PostgreSQL anyway.
Microsoft's new open-source extension, [pg_durable](https://github.com/microsoft/pg_durable), is a direct challenge to that entire stack. The pitch is blunt: stop handing durable execution to external services when you already have a perfectly good database that knows how to persist things to disk.
What "durable" actually means here
The word gets thrown around loosely in software, so it's worth being precise. In pg_durable, a durable function is a graph of steps that the extension tracks and checkpoints as it executes. The workflow state lives in the database. If your server crashes mid-execution, the work doesn't vanish—the extension picks up where it left off on restart. This is meaningfully different from a standard BEGIN...COMMIT block, which either succeeds atomically or rolls back entirely, and different again from a cron job, which simply doesn't know whether its last run finished, crashed, or is still running somewhere in the void.
What pg_durable adds is the middle ground: long-running, multi-step processes that survive failure and resume gracefully. The kind of thing you'd normally reach for Temporal or a message queue to handle.
According to Microsoft's official documentation at microsoft.github.io/pg_durable, the extension runs on PostgreSQL 17.
The API surface is deliberately minimal
The core interaction model is simple enough to explain in a sentence: you express your workflow as a SQL string, hand it to df_start(), and get back an eight-character ID you can use to poll status or retrieve results.
Better Stack's Warren walked through this in a recent video—starting with something almost absurdly minimal, a SELECT 'hello world' wrapped in df_start(), just to illustrate the shape of the thing. The trivial example is actually pedagogically smart. You see the return value (the ID), you see df_status() and df_result(), and you understand the pattern before anything interesting happens.
What makes the pattern interesting is the set of built-in operations it composes over. pg_durable ships with sequence execution (run step A, then step B), parallel execution (run A, B, and C simultaneously and wait for all of them), and race execution (run all and return whichever finishes first). There's also df.wait_for_schedule, which accepts a cron expression and pauses a workflow until that expression fires. No external scheduler. No crontab. Just SQL.
Scheduled jobs: a worked example
Warren's demo sets up a perpetual loop: every minute, pg_durable calls a stored procedure that refreshes materialized views and logs the operation. The workflow definition looks roughly like this:
SELECT df_start('
loop(
sequence(
wait_for_schedule(''* * * * *''),
call(''refresh_materialized_views'')
)
)
');
The loop runs forever. The sequence inside it says: wait one minute, then call the procedure. Then the loop wraps back around. You can watch the log table fill up in real time, a new row appearing every sixty seconds, with no cron daemon, no external worker process, and no queue infrastructure required.
This is where the "replace your cron" pitch actually lands. If your scheduled jobs are already touching PostgreSQL data, doing that scheduling inside PostgreSQL isn't a philosophical choice—it's an operational simplification.
Human-in-the-loop workflows
The more ambitious demo involves order approval: fetch the top order from the database, park the workflow, wait up to 24 hours for a human approval signal, then update the order status accordingly.
The key primitive here is df_signal(), a function that wakes a parked workflow. You run your approval script, call df_signal() with the workflow ID, and the suspended execution resumes and evaluates the outcome—approved or timed out—using the extension's built-in if function.
From Warren's walkthrough: "We're waiting on approval from our second script... if we run our approval script, the status now has switched to approved. The first script then exits because the approval has now happened."
This is the pattern that's genuinely hard to build well with cron jobs or simple queues. Human-in-the-loop logic requires something that can sleep for hours without blocking resources, resume on an external signal, and handle the timeout path gracefully. Temporal exists largely to solve this problem. pg_durable is arguing you can solve it in the database you already have.
The boilerplate question
Microsoft's announcement post on the Microsoft Community Hub includes a direct comparison: the queue setup, worker management, polling logic, message handling, state tracking, error handling, and retry logic that you'd normally write by hand collapses from 300 lines of boilerplate to 7 lines with pg_durable.
That number deserves some scrutiny. Three hundred lines is a real cost—but it's also a cost you typically pay once, wrap in a library, and mostly forget about. The more honest question is maintenance: what happens when that handbuilt queue infrastructure needs to change? Every layer you're not running is a layer you're not debugging at 2am.
Error handling and retries being automatic isn't just a code-volume story. It's a correctness story. Handbuilt retry logic tends to accumulate subtle bugs around exactly-once semantics, backoff strategies, and dead-letter handling. Having that baked into the extension by default is a meaningful reduction in the surface area where things go wrong.
The part worth watching carefully
There's an obvious question the extension doesn't answer from the outside: what are the performance and scalability characteristics of running orchestration logic inside the database? Temporal, Celery, and similar systems exist partly because keeping workflow state out of your primary database means your primary database stays fast and focused.
pg_durable is betting that for a large class of workloads—moderate concurrency, workflows that mostly wait on I/O or human input, teams that don't want to operate additional infrastructure—the overhead is worth the operational simplicity. That bet might be right for most applications most of the time. But "eliminate the external service" and "scale to tens of thousands of concurrent workflows" might not be compatible goals, and Microsoft's documentation doesn't make strong claims about the upper end.
This is genuinely new territory. The extension is fresh, the production war stories don't exist yet, and the community hasn't had time to find the sharp edges. Warren's demos are clean because they're demos. The interesting question is what happens when someone runs this under real production load and reports back.
For the developer who's been stitching together cron, Redis, and a handbuilt retry table to get something that barely works—pg_durable is probably a net improvement on day one. For the team already running Temporal at scale, the calculus is less clear. The extension is asking you to trade a specialized tool for a general one, and those trades always have a hidden cost somewhere.
Microsoft open-sourced this, which means the community gets to stress-test it. That's usually where the truth comes out.
Dev Kapoor covers open source and developer communities for Buzzrag.
We Watch Tech YouTube So You Don't Have To
Get the week's best tech insights, summarized and delivered to your inbox. No fluff, no spam.
More Like This
How Cloudflare Uses Lava Lamps to Encrypt the Internet
Cloudflare's San Francisco office has a wall of 100 lava lamps generating entropy for SSL/TLS encryption. Here's why computers can't be truly random.
Bridging the Gap: C++ Workshop Tackles Industry Reality
Amir Kirsh's workshop addresses the persistent divide between academic C++ and production code—and questions whether one-day training can solve it.
Dozzle: The Docker Log Viewer That Does Less (On Purpose)
Dozzle is a 7MB tool that streams Docker logs to your browser. No storage, no database, no complexity. Better Stack shows why that's the point.
When Your Competitor's Employee Builds Your Alternative
Headscale—Tailscale's open-source alternative—was built by a Tailscale employee. The setup complexity reveals why the company isn't worried.
PostgreSQL Explained for the Rest of Us
PostgreSQL powers much of the internet's data infrastructure. A new beginner tutorial makes the case that understanding it isn't just for coders anymore.
The Architecture That Makes a Home Lab Feel Enterprise
Brandon Lee's production home lab runs on Proxmox, Ceph, Talos, and GitOps. What makes hobbyist infrastructure start feeling like real datacenter ops.
Google's TurboQuant Claims Don't Survive Closer Inspection
Google's TurboQuant promised 6x memory savings for AI models. The fine print tells a different story about baselines, benchmarks, and research integrity.
RAG·vector embedding
2026-07-11This article is indexed as a 1536-dimensional vector for semantic retrieval. Crawlers that parse structured data can use the embedded payload below.