Cloudflare Workflows: quando migrar por frente editorial
Entenda quando separar frentes no Cloudflare Workflows, como preservar a idempotência e por que só uma rotina justifica adotar Dynamic Workflows.

No meu uso do Cloudflare Workflows, seis rotinas de publicação do lado da Anthropic são acionadas todos os dias, e todas fazem POST para um único PublishWorkflow estático, identificado por publish-{brief_id}. Em 1 de maio, a Cloudflare lançou @cloudflare/dynamic-workflows; poucos dias depois, chegou o Workflows V2, com um plano de controle reconstruído para a carga disparada por agentes. O mais interessante não é o lançamento. É que a escolha de manter um único workflow estático, feita para garantir idempotência, deixou de ser uma limitação herdada e passou a ser uma decisão que preciso justificar.
O que me surpreendeu
Eu esperava um anúncio do tipo “Workflows agora escala mais”. Limites maiores, mais espaço na fila, aquele aumento anual de sempre. Essa foi a parte menos importante da novidade.
O lançamento que realmente importa permite que o código do workflow varie por tenant em tempo de execução. @cloudflare/dynamic-workflows chegou em 1 de maio com licença MIT e foi desenvolvido sobre Dynamic Workers. A biblioteca permite registrar um único WorkflowEntrypoint cujo corpo é resolvido a partir de um Dynamic Worker no momento em que a instância é criada. Assim, o próprio grafo de etapas pode assumir o formato de cada tenant, em vez de ficar engessado no deploy. A Cloudflare resume a proposta como “execução durável que acompanha o tenant” — uma formulação precisa para quem já tentou encaixar lógica específica por cliente em um único workflow usando feature flags.
Minhas seis rotinas de publicação — news, dev, build, design, marketing, founders, business — funcionam, na prática, como seis tenants que compartilham um PublishWorkflow. Não são clientes, e sim rotinas de IA no lado da Anthropic, cada uma responsável por uma frente de conteúdo. Ainda assim, o modelo multitenant se encaixa perfeitamente: a mesma espinha dorsal de orquestração, com pequenas variações por frente, tudo despachado para a mesma conta da Cloudflare.
Poucos dias depois veio o Workflows V2, e o enquadramento daquele anúncio diz mais do que os números. A V2 foi explicitamente rearquitetada para instâncias de workflow criadas por agentes em velocidade de máquina, não por pessoas clicando em botões. É exatamente o padrão de acionamento que uso. Quando uma rotina de publicação decide colocar um artigo no ar, um evento não humano cria uma instância de execução durável; o plano de controle da V1 havia sido construído para outro perfil de carga.
Dynamic Workflows: execução durável que acompanha o tenant
Anúncio da Cloudflare sobre @cloudflare/dynamic-workflows, com licença MIT e desenvolvido sobre Dynamic Workers.
O que isso significa para fundadores sem perfil técnico
“Execução durável” parece uma expressão feita para afastar quem não é técnico. Em termos simples, é uma tarefa com várias etapas que sobrevive a uma falha e retoma do último ponto concluído, em vez de recomeçar do zero. Se a etapa 5 de 8 falhar porque uma API saiu do ar, o sistema tenta novamente a etapa 5 — sem repetir as etapas 1 a 4 e sem cobrar por elas outra vez.
É aqui que fundadores precisam prestar atenção: o limite de repetição por etapa também delimita o custo de cada etapa. Se o pipeline chama um modelo de IA pago na etapa 3 e outro na etapa 6, mas trava na etapa 7, o certo é repetir apenas a etapa 7, não o processo inteiro. Em um pipeline pago, uma nova execução não idempotente não gera apenas uma linha duplicada no banco de dados. Ela gera uma cobrança duplicada.
A decisão entre construir ou adiar cabe em uma frase para repassar a um prestador: separe os workflows por linha de produto somente quando a lógica dessas linhas realmente divergir, não apenas porque a plataforma passou a permitir isso. A Cloudflare acaba de lançar uma abstração poderosa, e toda abstração assim traz a tentação de redesenhar o sistema ao redor dela. Manter N definições de workflow custa N vezes mais; o benefício só aparece quando as frentes executam trabalhos genuinamente diferentes. Ao ouvir “agora que dá, deveríamos criar um workflow para cada linha de produto”, um fundador deveria perguntar o que mudou no trabalho — não o que mudou na plataforma.
A arquitetura que uso no Cloudflare Workflows
A arquitetura real é pequena o bastante para caber na cabeça. Cada rotina de publicação no lado da Anthropic termina sua pesquisa, prepara um brief e faz POST para /api/admin/publish no site. Esse endpoint valida o payload, gera um ID de instância e chama instances.create em um único WorkflowEntrypoint, chamado PublishWorkflow.
O workflow tem oito estágios idempotentes com step.do:
- validate (schema do brief, unicidade do slug)
- ground (busca de citações, resolução de links)
- generate (chamada ao Claude para produzir o corpo)
- clean (validação das diretivas de Markdown)
- persist (inserção no Postgres, versionamento)
- index (embeddings, atualização da busca)
- cover (geração de imagem + upload para o R2)
- publish (mudança de status, ping do sitemap)
export class PublishWorkflow extends WorkflowEntrypoint<Env, PublishParams> {
async run(event: WorkflowEvent<PublishParams>, step: WorkflowStep) {
const brief = await step.do("validate", () => validateBrief(event.payload));
const grounded = await step.do("ground", () => groundCitations(brief));
const draft = await step.do("generate", () => generateBody(grounded));
const cleaned = await step.do("clean", () => validateDirectives(draft));
const row = await step.do("persist", () => persistArticle(cleaned));
await step.do("index", () => reindex(row.id));
await step.do("cover", () => generateCover(row.id));
await step.do("publish", () => flipStatus(row.id));
}
}O limite de despacho tem este formato:
const id = `publish-${brief.brief_id}`;
try {
await env.PUBLISH.create({ id, params: brief });
} catch (e) {
if (isDuplicateIdError(e)) return new Response("already queued", { status: 200 });
throw e;
}instances.create lança um erro quando o ID já existe. Essa única linha sustenta uma parte enorme da arquitetura: é a única barreira que impede uma rotina da Anthropic, ao ser disparada novamente, de publicar o mesmo artigo duas vezes e me cobrar em dobro pelas chamadas de IA internas.
Por que uma definição para seis frentes? Porque os oito estágios são idênticos em todas elas. Só muda o pacote editorial — especificação de voz, perfil do público, lista de padrões a evitar e orientações do brief. Esses elementos seguem como dados em tempo de execução dentro do envelope de despacho, não como código. O nome da frente seleciona o pacote enviado à etapa 3 (generate); todas as outras etapas independem da frente.
O ponto de pressão — e o único motivo honesto para sequer discutir Dynamic Workflows — é que uma frente começa a exigir outro grafo de etapas, não apenas outro pacote. A frente mais intensiva em pesquisa quer uma rodada extra de fundamentação antes da geração e, possivelmente, uma etapa de checagem de fatos depois. Essa diferença é estrutural, não uma diferença de dados. Hoje isso funciona como um ramo condicional dentro de ground, mas é o tipo de solução que apodrece quando mais três frentes acrescentam suas próprias exceções.
Migração para Dynamic Workflows: custos e benefícios
É isso que createDynamicWorkflowEntrypoint oferece. O código do workflow de cada frente é carregado em tempo de execução a partir de um Dynamic Worker. Com isso, manter frentes que não foram acionadas hoje custa quase nada. Também desaparece a taxa de manutenção de ter “todas as frentes sempre implantadas no mesmo bundle”, e cada uma pode evoluir de forma independente sem um novo deploy da espinha dorsal compartilhada.

O custo real está justamente onde o anúncio passa mais rápido. Sai um WorkflowEntrypoint com tipos verificados — no qual o compilador avisa quando o contrato de entrada de uma etapa muda — e entram N definições carregadas em tempo de execução, sem esse alerta. Divergências nos contratos de etapas entre frentes deixam de falhar no build e passam a falhar em runtime. Com seis frentes, se a etapa persist esperar um formato de linha ligeiramente diferente em duas delas porque alguém refatorou apenas metade e esqueceu o restante, o problema só aparece quando um artigo real tenta ser publicado, não durante a CI.
A migração não precisa ser tudo ou nada. Fingir que precisa é o caminho mais curto para complicar o sistema sem necessidade. Este é o plano que pretendo seguir:
- Manter a espinha dorsal compartilhada de 8 estágios como um
WorkflowEntrypointestático. Esse é o caminho crítico. Cinco das seis frentes continuam usando-o sem alterações. - Criar a frente mais intensiva em pesquisa como um Dynamic Workflow, com grafo próprio (rodada adicional de fundamentação e etapa de checagem de fatos).
- Fazer o roteamento por frente no limite de
/publish: um switch de uma linha sobrebrief.lanedecide em qual binding chamarcreate.
Quando apagar o código do Cloudflare Workflow: agentes gerenciados, resultados e webhooks
A decisão inversa: quando os Anthropic Managed Agents tornam seu CF Workflow redundante.
A regra de decisão, agora com um número: migre uma frente para seu próprio Dynamic Workflow apenas quando o grafo dela diferir da espinha dorsal em mais de uma etapa. Abaixo desse limite, manter um ramo condicional na etapa existente custa menos do que uma segunda definição de workflow. Acima dele, o ramo começa a esconder o que a frente realmente faz, e uma definição separada passa a compensar.
Uma frente acima do limite. Cinco abaixo. Esse é o plano de migração em duas frases. Se um prestador me apresentasse a mesma proposta sugerindo dividir as seis em Dynamic Workflows logo no primeiro dia, eu não aprovaria. O custo de desenvolvimento é concreto, enquanto o benefício está concentrado em exatamente uma frente.
O que o Cloudflare Workflows V2 muda nos gatilhos de agentes
Os números de destaque da V2 são 50,000 instâncias simultâneas e 2,000,000 de instâncias na fila por workflow, contra 1,000,000 na V1. Não são métricas de vaidade, mas também estão muito longe da minha realidade. Com seis rotinas disparadas uma ou duas vezes por dia, opero cerca de nove ordens de grandeza abaixo do novo limite.
Cloudflare Workflows V2: replay determinístico e 50k instâncias simultâneas
Cobertura da InfoQ sobre a rearquitetura do plano de controle da V2 e os novos limites de simultaneidade.
Para o meu stack, os números não são o mais importante. O ponto decisivo é que o plano de controle da V2 foi reconstruído tendo a criação de instâncias por agentes como caso principal. A V1 era otimizada para o padrão acionado por humanos: alguém clica em um botão, uma instância começa, e o sistema absorve uma carga em rajadas, porém limitada. Na V2, o gatilho é um processo, não uma pessoa; a taxa depende da vazão dos agentes upstream, não de cliques em uma interface.
Vale traduzir o replay determinístico da V2 para linguagem direta. Cada etapa é isolada, pode ser repetida, é idempotente, e o workflow recomeça da última etapa concluída com sucesso. Essa é exatamente a propriedade que eu protegia manualmente no limite de despacho com o ID de instância publish-{brief_id}. A V1 já oferecia a garantia de repetição por etapa; a V2 reforça a semântica de replay, de modo que a propriedade estrutural que eu defendia também passa a ser imposta pela plataforma por baixo.
Na prática, a mudança desta semana é nenhuma no caminho crítico. A adoção do modelo V2 é opcional e exige um novo deploy; correr para mover um pipeline idempotente que funciona para outro plano de controle, apenas em busca de uma semântica que ele já tinha, é a pior decisão possível. Vou levar a frente de pesquisa para a V2 quando a criar como Dynamic Workflow, porque código novo no modelo novo custa pouco. As cinco frentes estáticas permanecem onde estão até surgir um motivo para mexer nelas que não seja “a plataforma lançou uma versão nova”.
A regra que não abro mão: idempotência em workflows
Usar publish-{brief_id} como ID da instância é essencial. Sem isso, o pipeline dispara outra vez quando uma rotina da Anthropic faz uma nova tentativa, publica o mesmo artigo duas vezes e cobra em dobro por cada chamada de API paga dentro do corpo do workflow.
Guardrails para agentes de IA em produção: um playbook para limitar o impacto
Etapas idempotentes formam uma camada de contenção. O ponto de controle de custos é a outra.
Dynamic Workflows não ameaça essa regra diretamente. O contrato do ID em instances.create não mudou. O risco aparece em uma refatoração descuidada por frente, quando o código local passa a recalcular o ID. Uma frente pode, por exemplo, decidir incluir um timestamp no ID “por segurança”, rompendo silenciosamente a deduplicação, já que cada nova tentativa passa a gerar um identificador exclusivo.
A regra que sobrevive a qualquer mudança de versão — e que eu escreveria na parede antes de deixar outra pessoa mexer no código — é esta:
Essa é uma daquelas regras que não aparecem em um anúncio nem em um guia de migração, pois só existem depois que alguém coloca em produção a falha que elas evitam. O outro lado desse ponto de controle de custos — impedir que uma única execução gere uma conta descontrolada mesmo se a deduplicação falhar — é uma camada separada, localizada nas chamadas aos modelos, não nas instâncias. As duas existem pelo mesmo motivo: em um pipeline no qual cada etapa custa dinheiro, correção estrutural é o seguro mais barato que existe.
O que eu faria diferente se começasse do zero em maio de 2026
Se estivesse começando este stack hoje, em vez de herdar decisões tomadas há um ano, eu mudaria três coisas.
Primeiro, começaria pela espinha dorsal estática compartilhada e acrescentaria um Dynamic Workflow para qualquer frente realmente divergente, em vez de criar seis definições distintas. Quando uma abstração nova chega, a tentação é aplicá-la em todo lugar; só que o custo de manter N definições de workflow aparece antes do benefício de escala. Seis definições significam seis lugares para corrigir um bug, seis lugares para atualizar uma dependência e seis lugares em que o contrato de uma etapa pode divergir. Uma espinha dorsal mais uma exceção é a divisão mínima viável.
Segundo, colocaria a chave de idempotência no limite HTTP desde o primeiro dia. Adotar publish-{brief_id} apenas depois de uma publicação duplicada é o caminho caro: é preciso reconciliar as linhas repetidas, ressarcir os custos afetados e instrumentar a camada de despacho com o sistema já em produção. Incluir o padrão try { create({id}) } catch (dup) {} antes da primeira publicação de um pipeline leva dez minutos e elimina toda uma categoria de falhas.
Terceiro, trataria o determinismo do Workflows V2 como o piso da arquitetura, não como um recurso para ativar depois. Toda etapa deve ser segura para replay, mesmo que o sistema nunca chegue ao limite de 50k execuções simultâneas. Segurança de replay não é uma característica de escala, mas de correção. Uma etapa que não tolera replay quebra durante uma nova tentativa — e novas tentativas acontecem em qualquer escala.
Esse último ponto é uma decisão técnica com postura de senioridade. A armadilha está em tratar novas capacidades da plataforma como recursos a adotar. A disciplina está em encará-las como restrições de projeto, mesmo que toda a capacidade disponível jamais seja usada.
Preciso de Dynamic Workflows se todos os meus tenants executam a mesma lógica?
Não. Quando o grafo de etapas é idêntico e apenas os dados mudam, envie esses dados no payload de despacho e mantenha um único workflow estático. Dynamic Workflows compensa quando o próprio código diverge por tenant — quando muda o grafo de etapas, não apenas os parâmetros dentro dele.
O Workflows V2 quebra workflows existentes na V1?
A V2 usa um plano de controle rearquitetado, voltado à execução determinística acionada por agentes. Trate a migração como opcional, valide a idempotência antes de mover um caminho crítico e não migre código que funciona apenas porque há uma nova versão.
Qual é o limite real de simultaneidade agora?
São 50,000 instâncias simultâneas e 2,000,000 na fila por workflow, contra 1,000,000 anteriormente. Para a maioria dos operadores, isso está muito acima da carga real; a propriedade mais importante da V2 é o replay determinístico, não o novo limite.
@cloudflare/dynamic-workflows está pronto para produção ou ainda é preview?
A biblioteca foi lançada em 1 de maio de 2026, sob licença MIT e desenvolvida sobre Dynamic Workers. Use a maturidade da biblioteca e o contrato de idempotência como critérios de risco, não a licença. Com uma camada de despacho sólida, a biblioteca fica pronta antes do seu plano de migração.
Quando vale a pena um fundador pagar um engenheiro para fazer essa migração?
Quando a lógica de automação de uma linha de produto realmente diverge das demais — um grafo de etapas diferente, não apenas outros parâmetros. Separar por escala é prematuro; separar por divergência de lógica é o gatilho real. Se sua equipe precisa de ajuda para fazer esse cálculo de migração, esse é exatamente o tipo de revisão de arquitetura que realizo pela DVNC.dev.
4 de set. de 2026







