Caiu ou Não?Pesquisar serviço
PT
Agentes e APIs

Durable Object com retry automático: evite chamadas duplicadas

Chamadas a Durable Objects agora recebem até quatro novas tentativas por padrão. Ajuste loops próprios, marque apenas métodos idempotentes e diagnostique as exceções.

Ilustração editorial de chamadas RPC para um Durable Object com tentativas automáticas e controle de idempotência

Resposta rápida

A Cloudflare passou a repetir automaticamente chamadas fetch e RPC para Durable Objects quando o runtime identifica uma falha transitória elegível. O padrão é uma chamada inicial e até quatro novas tentativas, dentro de uma janela de 10 segundos. A mudança não exige alteração no código para receber a proteção básica.

Revise agora qualquer loop de retry já existente, porque ele pode se combinar com as tentativas do runtime. Use maxRetries: 0 se quiser manter apenas o controle próprio. Marque um método com retryable() somente quando executá-lo novamente for seguro e idempotente; cobrar, enviar ou incrementar sem deduplicação não deve receber essa permissão.

O que mudou nas chamadas para Durable Objects

O retry automático vale para Worker chamando Durable Object e também para Durable Object chamando outro Durable Object, tanto por fetch quanto por RPC. Ele cobre falhas que acontecem antes de a requisição chegar ao objeto e quedas de conexão nas quais o cliente não consegue saber se o objeto recebeu a chamada. O runtime aplica backoff exponencial com jitter e nenhuma nova tentativa começa depois do limite de tempo configurado.

Por padrão são cinco tentativas totais: a original e quatro retries. As tentativas automáticas não contam no limite de subrequests. O comportamento já está ativo no runtime; Wrangler 4.158.0 ou posterior é necessário quando o projeto quer configurar retry no stub ou usar retryable() de forma tipada.

Quais erros são repetidos e quais ficam de fora

Um erro de chamada pode expor retryable como true quando é elegível. Ainda assim, a decisão e o número de tentativas são controlados pelo runtime. Erros lançados pelo seu código depois que a requisição chega ao Durable Object não são repetidos. Uma resposta HTTP 500 também é apenas uma resposta e não aciona esse mecanismo.

Erros com overloaded ficam fora dos retries automáticos para evitar ampliar uma sobrecarga. Nesse caso, reduza trabalho e frequência por objeto, aplique controle de entrada ou distribua a carga entre mais IDs. A página de status ajuda a identificar uma falha ampla, mas não substitui logs, métricas e a análise do ID específico que concentrou trabalho.

Como o runtime evita executar o método duas vezes

Quando a conexão cai depois de um envio incerto, a nova tentativa preserva a identidade interna da requisição. Se a primeira chamada chegou ao Durable Object, o runtime rejeita a duplicata e devolve o erro original. Por padrão, o método não é executado novamente nesse cenário, justamente para não duplicar efeitos cujo resultado ficou desconhecido.

Essa proteção é diferente de exactly once em um sistema externo. Se o método chamou uma API de pagamento, e-mail ou banco remoto, o destino ainda precisa aceitar uma chave de idempotência ou permitir consultar a operação anterior. O retry do Durable Object não deduplica sozinho efeitos executados fora da Cloudflare.

Quando usar retryable()

retryable() permite que o runtime execute novamente um método quando a entrega anterior ficou incerta e a chamada original talvez tenha chegado. A marcação não transforma um método em idempotente e não amplia os tipos de erro ou o número de tentativas. Ela apenas declara que repetir aquele método é seguro.

Leituras, substituição de um valor pelo estado desejado e operações deduplicadas por uma chave estável costumam ser candidatas depois de revisão. Incrementar saldo, consumir cota, enviar mensagem, criar pedido ou anexar cobrança sem chave de idempotência não são. Para aplicar a marcação, atualize Wrangler, importe retryable de cloudflare:durable-objects e marque o método no prototype da classe; a documentação também mostra a marcação do handler fetch.

  • Liste todas as escritas e chamadas externas feitas pelo método.
  • Defina uma chave estável que identifique o efeito ou torne a operação uma atribuição do estado desejado.
  • Teste a mesma chamada duas vezes e confirme que o estado final e os efeitos externos não se duplicam.
  • Aplique retryable() somente depois que esse teste passar.
  • Monitore tentativas, latência e efeitos após o deploy.

Como ajustar maxRetries e timeoutMs

O objeto retry pode ser passado ao obter um stub com get() ou getByName(). maxRetries aceita de 0 a 10 e tem padrão 4. timeoutMs aceita de 500 a 60.000 milissegundos e tem padrão 10.000. O timeout limita quando uma nova tentativa pode começar; não é uma garantia de cancelamento instantâneo de toda a operação já em andamento.

Use maxRetries: 0 quando a aplicação já possui um mecanismo próprio e você precisa evitar camadas sobrepostas. Reduza o número para operações sensíveis à latência e aumente apenas quando o contrato suporta espera, a chamada é segura e a dependência tem chance real de recuperação. Gere novamente os tipos com o comando do Wrangler adotado pelo projeto depois de atualizar a versão.

  • Atualize Wrangler para 4.158.0 ou posterior em uma branch de teste.
  • Mapeie cada loop de retry que envolve o stub, o Durable Object e serviços externos.
  • Escolha uma única camada responsável ou calcule explicitamente o total máximo de tentativas.
  • Configure maxRetries e timeoutMs no stub e simule uma falha transitória.
  • Valide latência, contagem de efeitos e comportamento quando o limite termina.

Cuidado com retries multiplicados

Um loop externo pode chamar o stub novamente depois que o runtime já fez até cinco tentativas totais. Se o Durable Object também chama outra dependência com retry, a quantidade de tentativas e a latência podem crescer em camadas. Não multiplique os números como uma previsão exata sem medir, mas trate a composição como um limite operacional que precisa ser calculado e testado.

Registre um identificador de operação, o número da tentativa da aplicação e o resultado, sem salvar segredos ou payloads sensíveis. Remova loops redundantes, mantenha jitter onde o retry continua necessário e defina um orçamento de tempo para o fluxo completo. Em agentes, interrompa a ferramenta com um erro claro em vez de insistir além do tempo útil da conversa.

Chamadas que não recebem retry automático

A proteção não é aplicada a fetch com corpo de requisição em streaming. Em RPC, ficam de fora argumentos que contêm stream, stub, função ou RpcTarget, além de promise pipelining e stubs enviados ou devolvidos como argumentos e resultados. Esses formatos têm estado de comunicação que não pode ser repetido pelo runtime da mesma forma que dados serializáveis comuns.

Se o fluxo usa um desses recursos, trate a falha explicitamente e prefira passar um identificador durável em vez de um objeto de conexão quando o desenho permitir. Não remova a capacidade avançada apenas para obter retries: compare a necessidade de streaming ou pipelining com o custo de implementar recuperação, checkpoint e nova chamada no nível da aplicação.

Como diagnosticar falha, timeout e overload

Comece pelo erro retornado e verifique retryable e overloaded. Depois compare horários, ID do objeto, latência e logs dos dois lados da chamada. Uma falha elegível pode já ter consumido as tentativas automáticas antes de chegar ao seu catch. Um overload pede redução ou distribuição de carga, não outro loop agressivo.

Consulte o Cloudflare Status para verificar incidentes amplos e use o diagnóstico web para testar DNS, TLS e HTTP da rota pública que inicia o fluxo. Esses testes não enxergam a chamada RPC interna nem provam que um efeito foi executado uma única vez. Para isso, use métricas, identificadores de operação e verificação do estado no sistema de destino.

Limitações e próxima ação útil

Este guia foi verificado em 6 de novembro de 2026. O retry automático melhora a recuperação de falhas transitórias entre chamadas, mas não repete erros da sua lógica, respostas HTTP 500, overload nem os formatos de streaming e RPC excluídos. Também não substitui checkpoint, deduplicação de efeitos externos, timeout do fluxo ou testes de reinicialização.

Escolha hoje uma chamada RPC de homologação. Remova ou desative o loop redundante, mantenha o padrão de quatro retries, provoque uma falha de conexão e confirme que a operação termina sem efeito duplicado. Depois teste maxRetries: 0 e um método realmente idempotente com retryable() antes de alterar qualquer caminho de cobrança, envio ou escrita crítica em produção.

Faça o próximo teste

Fontes consultadas

Os links abaixo servem para conferir conceitos, orientações oficiais e o critério editorial usado neste conteúdo.

Outros guias ligados ao mesmo tipo de problema.