Databases
How to Build Durable Workflows Directly in Postgres Without External Orchestrators
Relational databases can coordinate reliable, crash-resistant workflows without adding separate orchestration systems—using only SQL primitives and existing infrastructure.
InfoQ
Building automation systems that survive failures demands durable execution—the ability to checkpoint progress and resume from where work left off. Rather than deploying a dedicated orchestrator like Temporal or AWS Step Functions, teams already running Postgres can turn their primary database into a workflow coordinator, eliminating a stateful external dependency.
Kestrel Workflows, an incident-response and CI/CD automation platform, took this approach and found it simplifies the stack while collapsing reliability into one well-understood system. Here's how it works.
Why Skip the External Orchestrator#
Conventional wisdom suggests delegating durable execution to purpose-built services. These orchestrators sit between your application and workflow execution, handling dispatch, queuing, checkpointing, and reassignment. But each one introduces operational burden: another stateful system to secure, monitor, upgrade, and run. It becomes a single point of failure for all workflows, requires separate access controls and audit trails, and typically stores state in a key-value model that resists relational queries.
The insight is straightforward: durable execution is fundamentally about persisting state to an external system. If you already operate Postgres as your system of record and have invested in its reliability, why not use it directly?
Postgres as the Orchestrator#
With no separate orchestrator process, application servers run embedded workflow logic and query Postgres directly. A workflow_executions table holds each active workflow, and stateless workers poll it to claim work. The magic hinges on a single SQL primitive: FOR UPDATE SKIP LOCKED.
The Concurrency Trick#
This clause transforms an ordinary table into a safe work queue:
SELECT id, input
FROM workflow_executions
WHERE status = 'enqueued'
ORDER BY created_at
LIMIT 1
LOCKED;

