Imagina o seguinte cenário: você tem um pipeline que processa documentos, chama uma API externa para gerar embeddings, faz upsert no pgvector e atualiza um status. No meio do caminho, o banco reinicia. Com sorte, você descobre rápido. Sem sorte, ficam registros fantasma — metade processados, metade não — e ninguém sabe onde o processo parou.
Esse tipo de dor é tão comum que criou uma indústria inteira. Temporal, Airflow, Step Functions, Inngest, Restate, DBOS… a lista de orquestradores de workflow não para de crescer. Todos tentam resolver o mesmo problema: como garantir que uma sequência de passos rode até o fim, mesmo quando tudo dá errado no meio?
A Microsoft resolveu jogar uma bomba nesse mercado. Liberou em open source o pg_durable, uma extensão PostgreSQL que traz execução durável dentro do banco de dados. Sem serviço externo. Sem fila. Sem worker separado. Tudo roda como um background worker do próprio Postgres.
E a comunidade tech pirou. O projeto explodiu no Hacker News em poucas horas, com desenvolvedores divididos entre “isso é genial” e “isso é uma péssima ideia”. Vamos destrinchar.
O que é execução durável (e por que você deveria se importar)
Antes de falar do pg_durable em si, vale nivelar o conceito. Execução durável (durable execution) é a garantia de que um fluxo de trabalho vai rodar até o final, não importa o que aconteça no meio — crash do servidor, timeout de rede, restart do container, failover do banco.
Na prática, funciona assim: cada passo do workflow faz um checkpoint. Se algo falha, a execução retoma do último checkpoint salvo, sem repetir o que já foi feito. É como um save game automático, mas para código de backend.
Sem execução durável, você precisa:
- Tabelas de controle manuais para rastrear “onde parei”
- Lógica de idempotência em cada etapa
- Filas mortas para reprocessamento
- Jobs de reconciliação que rodam de madrugada
Com execução durável, isso desaparece. O runtime cuida de tudo.
Até agora, a ferramenta mais conhecida nesse espaço era o Temporal — um sistema distribuído robusto com SDKs para Go, Java, Python, TypeScript e mais. O problema? Temporal é um cluster inteiro que você precisa operar. Frontend service, History service, Matching service, um banco separado (Cassandra, MySQL ou Postgres) por trás… a complexidade operacional não é trivial.
E é exatamente aí que o pg_durable entra.
pg_durable: workflow durável como extensão do Postgres
O pg_durable é uma extensão PostgreSQL escrita em Rust (usando pgrx) que adiciona um runtime de execução durável dentro do processo do banco de dados.
A instalação é ridiculamente simples:
-- No postgresql.conf, adicione ao shared_preload_libraries
-- shared_preload_libraries = 'pg_durable'
CREATE EXTENSION pg_durable;
A partir daí, você define workflows usando uma DSL SQL com operadores composicionais. Parece estranho no início, mas faz sentido quando você entende a lógica.
Os operadores
| Operador | Função | ||
|---|---|---|---|
| ———- | ——– | ||
~> |
Encadeamento sequencial (step A, depois step B) | ||
| `\ | =>` | Substituição de variável (resultado do step anterior vira input do próximo) | |
& |
Execução paralela (fan-out) | ||
?> |
Branching condicional | ||
@> |
Loop |
E funções utilitárias como:
df.http()— chamadas HTTP diretas do bancodf.wait_for_signal()— pausa até receber um sinal externo (human-in-the-loop)df.sleep()— delays duráveis (sobrevivem restart)df.join()— junta resultados de execuções paralelas
Um exemplo real
Digamos que você quer processar documentos para um pipeline RAG:
SELECT df.start(
-- Busca documentos não processados
'SELECT id, content FROM documents WHERE processed = false LIMIT 100'
|=> 'batch'
-- Para cada documento, gera embedding via API
~> 'SELECT df.http(
''POST'',
''https://api.openai.com/v1/embeddings'',
json_build_object(''input'', $batch.content, ''model'', ''text-embedding-3-small'')
)'
|=> 'embeddings'
-- Upsert no pgvector
~> 'INSERT INTO document_embeddings (doc_id, embedding)
SELECT d.id, e.embedding
FROM unnest($batch) d, unnest($embeddings) e
ON CONFLICT (doc_id) DO UPDATE SET embedding = EXCLUDED.embedding'
-- Marca como processado
~> 'UPDATE documents SET processed = true WHERE id = ANY($batch.id)'
);
Se o Postgres cair entre o passo 2 e o 3, na volta ele sabe que os embeddings já foram gerados e pula direto para o upsert. Zero retrabalho. Zero dado corrompido.
A arquitetura por baixo
O pg_durable não é mágica — é engenharia bem feita em cima de dois componentes Rust:
duroxide — o runtime de orquestração. Implementa replay determinístico, checkpoints, sub-orquestrações e timers. Pense nele como o “motor” do Temporal, mas rodando in-process.
duroxide-pg — o state provider. Persiste todo o estado do runtime em um schema dedicado (duroxide.*) no próprio PostgreSQL. O estado do workflow é o estado do banco. Um backup PITR do banco restaura inclusive os workflows em execução.
O sistema roda como um background worker do PostgreSQL. Isso significa:
- Sem processo externo
- Sem fila de mensagens
- Sem Redis, RabbitMQ ou Kafka
- A durabilidade do workflow é a durabilidade do Postgres
Essa arquitetura tem uma consequência interessante: se você já faz backup/restore do Postgres (e deveria), seus workflows duráveis estão automaticamente cobertos. Um pg_basebackup captura tudo — dados, estado dos workflows, checkpoints.
Quando isso faz sentido (e quando não faz)
Eu já vi gente no Hacker News dizendo que isso é “colocar lógica de negócio no banco de dados” e que é um anti-pattern. A real? Depende do contexto.
Faz sentido quando:
- Seus dados e workflows vivem no mesmo Postgres — se o pipeline lê e escreve no banco, por que adicionar um Temporal no meio?
- Você quer infraestrutura mínima — startups e times pequenos que não querem operar um cluster Temporal
- Pipelines de dados / ETL — chunk, transform, load com checkpoint automático
- Manutenção de banco agendada — detectar bloat, esperar aprovação, executar VACUUM
- Workflows com human-in-the-loop — aprovações que podem demorar dias (o
df.wait_for_signal()sobrevive restarts)
Não faz sentido quando:
- Sub-milissegundo é requisito — o checkpoint tem custo; se cada step precisa responder em < 1ms, esqueça
- Workflows heterogêneos — se você orquestra microsserviços em 5 linguagens diferentes, o Temporal ainda é melhor
- Scale-out extremo — o throughput ceiling é o próprio Postgres. Para milhões de workflows simultâneos, a arquitetura distribuída do Temporal ganha
- Ambientes que não permitem extensões — RDS sem suporte a extensões customizadas, por exemplo
O elefante na sala: lógica no banco de dados
A discussão mais acalorada no Hacker News girou em torno disso. Um desenvolvedor comentou: “I kind of prefer my queue logic to be in code, in Git.” E ele tem um ponto válido.
Quando você define workflows em SQL dentro do banco, perde:
- Versionamento fácil — SQL em tabelas não aparece no
git diff - Code review — seu PR não mostra a mudança no workflow
- Testes unitários — testar SQL procedural é historicamente doloroso
- IDE support — sem autocomplete, sem linting, sem breakpoints
Por outro lado, a equipe da Microsoft argumenta que os workflows podem (e devem) ser definidos em scripts SQL versionados no Git e aplicados via migração, como qualquer DDL. O workflow roda no banco, mas a definição vive no código.
A equipe também revelou que seus clientes “split pretty evenly into 2 camps” — metade prefere lógica no banco, metade prefere separação total. O pg_durable atende o primeiro grupo.
pg_durable vs. o mundo: uma comparação honesta
| Critério | pg_durable | Temporal | DBOS | Restate | |
|---|---|---|---|---|---|
| ———- | ———– | ———- | —— | ——— | |
| Infraestrutura necessária | Só Postgres | Cluster Temporal + banco | Só Postgres | Servidor Restate | |
| Linguagem dos workflows | SQL | Go, Java, Python, TS | Python, TS | Java, TS, Rust, Go | |
| Curva de aprendizado | Média (DSL nova) | Alta (conceitos novos) | Baixa (decorators) | Média | |
| Escala máxima | Limitado ao Postgres | Praticamente ilimitado | Limitado ao Postgres | Alta | |
| Observabilidade | SQL queries no estado | UI dedicada + métricas | SQL queries | UI dedicada | |
| Maturidade | Preview (2026) | Produção (desde 2020) | GA (2025) | GA (2025) | |
| Licença | PostgreSQL License | MIT | MIT | Business Source |
O DBOS merece menção especial porque segue filosofia parecida — execução durável backed by Postgres. A diferença é que o DBOS é uma biblioteca em Python/TypeScript, enquanto o pg_durable é uma extensão do banco. No DBOS, você escreve código na sua linguagem favorita com decorators; no pg_durable, você escreve SQL.
Para quem já vive dentro do Postgres (DBAs, times de dados, backends data-heavy), o pg_durable encurta muito o caminho. Para quem prefere escrever workflows em Python com type safety e testes unitários, o DBOS ou Temporal continuam mais ergonômicos.
Segurança e multi-tenancy
Um detalhe que passou batido na maioria das análises: o pg_durable implementa Row-Level Security nativo. Cada usuário do banco só enxerga seus próprios workflows.
-- Concede acesso a um role específico
SELECT df.grant_usage('app_role');
Variáveis são isoladas por namespace via df.vars, e o background worker roda com role de superuser enquanto os workflows executam no contexto do role que os criou. Para ambientes multi-tenant (SaaS, plataformas), isso é relevante.
O que isso significa para o ecossistema Postgres
O PostgreSQL já é um canivete suíço. PostGIS para geoespacial, pgvector para IA, TimescaleDB para séries temporais, Citus para sharding. Agora soma pg_durable para orquestração de workflows.
A tendência é clara: em vez de adicionar mais serviços na arquitetura, consolida tudo no Postgres. Menos operação, menos latência de rede, menos pontos de falha. O trade-off é concentração de risco — se o Postgres cai, tudo cai.
Mas pra ser honesto, pra 90% dos projetos isso já era verdade antes do pg_durable. Se o banco morre, a aplicação morre junto. A questão é se você quer também operar um Temporal ou se prefere que o Postgres cuide de mais essa responsabilidade.
Setup rápido para testar
Se quiser botar a mão na massa:
# Clone o repositório
git clone https://github.com/microsoft/pg_durable.git
cd pg_durable
# Inicie o ambiente de desenvolvimento
./scripts/pg-start.sh
# Conecte ao Postgres
~/.pgrx/17.*/pgrx-install/bin/psql -h localhost -p 28817 -d postgres
# Ative a extensão
CREATE EXTENSION pg_durable;
Requisitos: PostgreSQL 17 ou 18, Rust nightly, cargo-pgrx 0.16.1. Também existem pacotes .deb para quem não quer compilar.
Para produção no Azure, o HorizonDB já vem com pg_durable integrado, auto-scaling até 128 TB e pipelines de IA nativos. Se você está na nuvem da Microsoft, esse é o caminho mais rápido.
Um caso de uso que ninguém mencionou: agentes de IA
Com o boom de agentes autônomos em 2026, execução durável virou infraestrutura crítica. Um agente que pesquisa, raciocina, chama ferramentas e gera output pode levar minutos — às vezes horas — para completar uma tarefa. Se o processo morre no meio, o agente precisa recomeçar do zero? Queimar tokens de novo?
O pg_durable resolve isso de forma elegante. Cada chamada de tool vira um step com checkpoint. O resultado da pesquisa? Salvo. A resposta da API de embeddings? Salva. Se cair, o agente retoma exatamente de onde parou, sem re-processar nem re-gastar tokens.
A própria Microsoft mencionou que já usa pg_durable internamente para “AI workflows” e que a redução de código e aumento de confiabilidade foram substanciais. Com agentes ficando mais complexos e mais caros de rodar, ter checkpoints automáticos não é luxo — é economia.
Pesquisadores da Zylos AI publicaram um paper em fevereiro de 2026 sobre padrões de execução durável para agentes autônomos, e a conclusão é clara: sem durabilidade, agentes que rodam por mais de 5 minutos têm taxa de falha inaceitável em produção. O pg_durable ataca exatamente esse gap.
Pra quem é o pg_durable em 2026?
Se eu tivesse que resumir em uma frase: pg_durable é para times que já tratam o PostgreSQL como plataforma, não apenas como banco de dados.
Times de dados que já usam pgvector, DBAs que já escrevem stored procedures complexas, backends monolíticos onde o Postgres é o centro de gravidade — esse pessoal vai adorar. A promessa de “zero infraestrutura adicional” não é marketing vazio quando você já tem um Postgres rodando.
Agora, se você opera microsserviços em 4 linguagens com deploy via Kubernetes, o Temporal continua sendo a escolha pragmática. O pg_durable não veio para matar o Temporal — veio para atender um público que o Temporal nunca atendeu bem: quem quer resolver o problema sem sair do banco.
O projeto está em preview, a Microsoft está aceitando feedback, e o código é PostgreSQL License (basicamente MIT). Se workflow durável é um problema que você resolve hoje com gambiarras de tabela de controle e cron jobs, vale testar. Na pior das hipóteses, você aprende uma DSL nova. Na melhor, joga fora umas 500 linhas de código de orquestração caseira.
Fonte de inspiração: pg_durable no GitHub — Microsoft Open Source













