Shopping cart

Subtotal $0.00

View cartCheckout

Building better devs

TnewsTnews
  • Home
  • Banco de Dados
  • Adeus Temporal? Microsoft Colocou Execução Durável Dentro do PostgreSQL
Banco de Dados

Adeus Temporal? Microsoft Colocou Execução Durável Dentro do PostgreSQL

pg_durable PostgreSQL durable execution Microsoft open source
Email : 13

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 banco
  • df.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

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Posts