Em sistemas distribuídos, uma falha de comunicação nem sempre significa que uma operação não pode ser concluída. Muitas vezes, o problema é temporário: uma conexão pode ficar indisponível por alguns segundos, um serviço pode demorar mais do que o esperado para responder ou uma aplicação pode ficar momentaneamente sobrecarregada.
Esse problema aparece com frequência em sistemas que processam dados produzidos por veículos conectados.
Imagine um veículo equipado com sensores capazes de coletar continuamente dados como velocidade, temperatura do motor, rotação, pressão e localização. Após captar essas informações, a Unidade Embarcada (On-board Unit – OBU), instalada no interior do veículo, envia os dados para uma plataforma responsável pelo processamento da telemetria. Para isso, a comunicação utiliza redes de telecomunicações, cuja infraestrutura de acesso móvel inclui as Estações Rádio Base (ERB).
Durante o trajeto dos dados entre a placa de rede da Unidade Embarcada (On-board Unit – OBU) e a Estação Rádio Base (ERB), podem ocorrer perdas de pacotes, aumento da latência e jitter elevado. Isso pode acontecer, por exemplo, em condições adversas, como chuva intensa, tempestades, descargas atmosféricas, baixa cobertura de sinal, interferências eletromagnéticas, obstáculos físicos, congestionamento da rede ou durante a transição entre diferentes ERBs (handover). Como consequência, a comunicação pode apresentar atrasos, perda temporária de conectividade e falhas na entrega dos dados ao servidor.
Por isso, para evitar a perda de pacotes que não conseguiram chegar à plataforma responsável pelo processamento da telemetria, uma estratégia adequada é utilizar o Retry Pattern. Descartar o pacote na primeira falha pode significar perder parte do histórico do veículo. Nesse tipo de situação, o Retry Pattern permite realizar uma nova tentativa quando existe uma possibilidade razoável de recuperação.
O que é Retry Pattern?
O Retry Pattern é um padrão de resiliência que permite repetir uma operação após uma falha temporária.
Em vez de considerar a operação definitivamente perdida após o primeiro erro, o sistema pode realizar uma nova tentativa. Dessa forma, uma falha temporária não precisa resultar imediatamente na perda da operação:

Martin Kleppmann estabelece uma distinção importante entre erros que justificam uma nova tentativa e aqueles em que repetir a operação não produzirá resultado diferente:
“Only transient errors (for example due to deadlock, isolation violation, temporary network interruptions and failover) are worth retrying; retrying a permanent error (e.g. constraint violation) would be pointless.”
Martin Kleppmann, Designing Data-Intensive Applications, p. 224.
Em outras palavras, Retry deve ser aplicado apenas para falhas transitórias. Se o erro for permanente, repetir a operação não resolverá o problema.
Como funciona?
Considere um veículo produzindo dados de telemetria:

Em determinado momento, a Unidade Embarcada (On-board Unit – OBU) gera o seguinte registro de telemetria:
{
"vehicleId": "VH-2048",
"timestamp": "2026-08-03T18:42:15Z",
"speed": 87,
"engineTemperature": 91,
"rpm": 2450
}
Em seguida, a Unidade Embarcada (On-board Unit – OBU) tenta enviar o registro para o Serviço de Ingestão.
No entanto, naquele momento, o veículo atravessa uma região com conectividade instável, como mostra a figura abaixo.

A primeira tentativa falha.
Em vez de descartar imediatamente o dado, a Unidade Embarcada (On-board Unit – OBU) mantém a informação temporariamente em sua memória interna. Em seguida, tenta transmiti-la novamente após um intervalo de espera.

Quando a conexão entre a Unidade Embarcada (On-board Unit – OBU) e a Estação Rádio Base (ERB) é restabelecida, a OBU envia o dado ao Serviço de Ingestão. A partir daí, o registro segue pelo pipeline de processamento.
Quando é necessário?
Retry é útil principalmente quando existe uma possibilidade razoável de que uma nova tentativa produza um resultado diferente.
No exemplo do veículo, isso pode acontecer quando existe:
- Perda temporária da conexão móvel.
- Timeout durante o envio.
- Indisponibilidade momentânea do Serviço de Ingestão.
- Falha temporária durante o processamento.
- Limitação momentânea de capacidade do serviço.
Mas Retry não deve ser aplicado indiscriminadamente.
Se o registro possui um formato inválido, por exemplo, repetir o mesmo envio não corrigirá o problema.
Da mesma forma, uma regra de negócio rejeitada ou uma violação permanente de uma restrição não se tornam válidas apenas porque a operação foi executada novamente.
A distinção entre uma falha transitória e uma falha permanente é, portanto, uma das decisões mais importantes na implementação do Retry Pattern.
Exponential Backoff e Jitter
Realizar novas tentativas imediatamente, porém, pode criar outro problema. Imagine milhares de veículos conectados ao mesmo serviço.
Se o Serviço de Ingestão ficar indisponível por alguns segundos e todas as Unidades Embarcadas (On-board Units – OBUs) tentarem novamente ao mesmo tempo, a própria recuperação pode gerar uma nova sobrecarga no serviço:

Uma estratégia utilizada para reduzir esse problema é o Exponential Backoff. Nesse mecanismo, o intervalo entre as tentativas aumenta progressivamente:

Kleppmann também alerta que, quando um erro ocorre devido à sobrecarga, repetir a operação pode piorar o problema. Entre as medidas mencionadas estão limitar o número de retries e utilizar Exponential Backoff:
“If the error is due to overload, retrying the transaction will make the problem worse, not better. To avoid such a feedback cycle, limit the number of retries, use exponential backoff, and handle overload-related errors differently from other errors (if possible).”
Martin Kleppmann, Designing Data-Intensive Applications, p. 223.
No entanto, ainda existe outro problema.
Se milhares de Unidades Embarcadas (On-board Units – OBUs) utilizarem exatamente os mesmos intervalos, todas poderão tentar novamente praticamente ao mesmo tempo. Nesse cenário, entra o Jitter.
O Jitter, por sua vez, adiciona uma pequena variação aleatória ao intervalo de espera:

Assim, as novas tentativas ficam distribuídas ao longo do tempo, reduzindo a possibilidade de uma grande quantidade de Unidades Embarcadas (On-board Units – OBUs) atingir o Serviço de Ingestão simultaneamente.
Na prática, a estratégia combina:
- Retry: define se uma nova tentativa será realizada.
- Exponential Backoff: define como o intervalo entre as tentativas aumenta.
- Jitter: adiciona uma variação nesse intervalo, evitando que diversas Unidades Embarcadas (On-board Units – OBUs) executem Retry simultaneamente.
Retry e Idempotência
Além disso, existe outro problema importante.
Imagine que o Serviço de Ingestão tenha recebido um pacote de dados enviado por uma Unidade Embarcada (On-board Unit – OBU). Entretanto, devido a uma falha ou à perda da resposta de confirmação, a OBU não consegue determinar se o serviço recebeu e processou o pacote com sucesso. Como consequência, o mecanismo de Retry pode realizar uma nova tentativa e reenviar o mesmo pacote.
Nesse cenário, o reenvio pode resultar no processamento duplicado do mesmo dado. Para evitar esse problema, o sistema utiliza Idempotência em conjunto com o mecanismo de Retry. Dessa forma, o Serviço de Ingestão consegue identificar uma solicitação já processada e evitar a execução duplicada da mesma operação.
Então, como aplicar um Retry Idempotente? Uma abordagem consiste em associar a cada pacote de dados um identificador único, utilizado como Idempotency-Key, por exemplo:
{
"eventId": "EVT-839201",
"vehicleId": "VH-2048",
"timestamp": "2026-08-03T18:42:15Z",
"speed": 87,
"engineTemperature": 91,
"rpm": 2450
}
Ao receber novamente EVT-839201, o sistema consegue reconhecer que aquele evento já foi processado e evitar efeitos duplicados.
É aqui que Retry e Idempotência se encontram.
Sam Newman explica:
“In idempotent operations, the outcome doesn’t change after the first application, even if the operation is subsequently applied multiple times. If operations are idempotent, we can repeat the call multiple times without adverse impact.”
Sam Newman, Building Microservices: Designing Fine-Grained Systems, p. 215.
Newman relaciona esse comportamento diretamente à recuperação de falhas. Segundo essa abordagem, a idempotência é útil quando precisamos repetir mensagens sem ter certeza de que elas já foram processadas anteriormente.
Esse comportamento é especialmente importante em arquiteturas distribuídas, nas quais nem sempre o cliente consegue saber se a tentativa anterior falhou antes ou depois do processamento.
Kleppmann chama atenção exatamente para esse problema: uma operação pode ter sido concluída no Serviço de Ingestão, mas a comunicação pode falhar durante o envio da confirmação. Nesse caso, a Unidade Embarcada (On-board Unit – OBU) interpreta a ausência da confirmação como uma falha, e uma nova tentativa pode executar a operação duas vezes caso não exista um mecanismo de deduplicação.
“If the transaction actually succeeded, but the network failed while the server tried to acknowledge the successful commit to the client […] then retrying the transaction causes it to be performed twice — unless you have an additional application-level deduplication mechanism in place.”
Martin Kleppmann, Designing Data-Intensive Applications, p. 223.
Por isso, Retry não deve ser analisado isoladamente da Idempotência quando a operação produz efeitos que não podem ser duplicados.
Retry vs Circuit Breaker
Retry é adequado quando acreditamos que a falha pode ser temporária. No entanto, imagine que o serviço responsável pelo processamento da telemetria esteja completamente indisponível. Continuar tentando indefinidamente não ajudará. Nesse cenário, outro padrão pode entrar em ação: o Circuit Breaker.
Enquanto Retry procura responder:
“Vale a pena tentar novamente?”
Circuit Breaker procura responder:
“Essa dependência está falhando tanto que devemos parar temporariamente de chamá-la?”
O fluxo pode ser representado assim:

Quando o circuito está aberto, o sistema deixa temporariamente de encaminhar novas chamadas para a dependência indisponível. Depois de determinado período, pode permitir algumas chamadas para verificar se a dependência voltou a responder.
Retry e Circuit Breaker, portanto, não resolvem exatamente o mesmo problema.
Retry procura recuperar uma operação diante de uma falha transitória e Circuit Breaker procura impedir que o sistema continue insistindo em uma dependência que apresenta falhas persistentes.
Os dois padrões podem trabalhar em conjunto dentro de uma estratégia de resiliência. Mais detalhes sobre Circuit Breaker ficam para outro artigo.
Conclusão
O Retry Pattern é uma estratégia de resiliência para lidar com falhas transitórias em sistemas distribuídos.
No cenário de veículos conectados, uma interrupção momentânea da rede não precisa necessariamente resultar na perda dos dados produzidos pelos sensores. Nesse caso, a OBU pode preservar a informação e realizar novas tentativas quando houver possibilidade de recuperação.
Entretanto, o Retry Pattern precisa ser controlado para evitar novas sobrecargas e efeitos duplicados.
Exponential Backoff reduz a frequência das novas tentativas. Além disso, o Jitter evita que milhares de dispositivos tentem novamente simultaneamente, enquanto a Idempotência protege o sistema contra os efeitos do processamento repetido de uma mesma operação.
Por fim, quando as falhas deixam de ser temporárias e passam a ocorrer continuamente, mecanismos como Circuit Breaker podem impedir que o sistema continue insistindo em uma dependência indisponível.
Em sistemas distribuídos, portanto, resiliência não significa evitar todas as falhas. Significa projetar o sistema sabendo que elas inevitavelmente acontecerão e definindo como cada componente deve reagir quando ocorrerem.
