Software resiliente: 5 práticas inegociáveis para aguentar produção

  • Claudio Santos
Resilient software — the practices that keep a system running when failure happens

Resiliência não é sobre nunca falhar. É sobre o que o sistema faz quando a falha acontece.

Depois de anos integrando sistemas que nunca foram feitos para conversar entre si, uma coisa ficou clara: timeout, retry e webhook duplicado não são exceção. São o comportamento esperado de qualquer sistema distribuído em produção. Por isso, software resiliente não é um luxo de arquitetura — é o que separa um sistema que aguenta o mundo real de um que só funcionou na apresentação.

A seguir, cinco práticas que considero inegociáveis para quem constrói software que precisa aguentar carga real, e não apenas o ambiente de testes.

A realidade: todo sistema em produção vai falhar

Não é pessimismo, é estatística. Em produção, mais cedo ou mais tarde:

  • a rede cai;
  • o timeout acontece;
  • uma dependência externa sai do ar;
  • um webhook chega duplicado.

Isso não é hipótese. É o dia a dia de qualquer sistema distribuído. Quem projeta assumindo que "vai dar tudo certo" está, na prática, terceirizando o problema para o cliente descobrir.

O que realmente diferencia um sistema resiliente

A diferença não está em evitar a falha. Está em como o sistema se comporta quando ela acontece. Um sistema resiliente absorve o erro, se recupera e mantém a consistência — sem que o usuário perceba, ou percebendo o mínimo possível. As cinco práticas abaixo são como se chega lá.

1. Idempotência como padrão

Se a sua integração assume que cada chamada chega uma única vez, ela vai quebrar. Questão de quando, não de se.

Timeouts, retries e reentregas de webhook fazem a mesma mensagem chegar mais de uma vez. Idempotência é a garantia de que processar a mesma mensagem duas vezes tem o mesmo efeito de processá-la uma. Na prática: use uma chave de idempotência (um identificador único da operação), registre o que já foi processado e, se o mesmo evento voltar, responda com sucesso sem repetir o efeito.

Sem isso, um simples retry vira cobrança ou crédito em duplicidade — o tipo de bug que custa dinheiro de verdade.

2. Retry com critério

Retry ajuda. Retry ingênuo destrói.

Repetir sem backoff e sem limite não resolve instabilidade — transforma uma instabilidade pontual em sobrecarga generalizada. É o efeito manada: todo mundo tentando de novo ao mesmo tempo, derrubando de vez a dependência que já estava frágil.

O critério envolve três coisas: backoff exponencial com jitter (espaçar as tentativas, com aleatoriedade para não sincronizar todos os clientes), um limite de tentativas e um circuit breaker que para de insistir numa dependência que já está no chão. E lembrar sempre: retry é para falha transitória, não para erro permanente.

3. Observabilidade desde o dia 1

Não dá para tratar o que não se enxerga. Logs, métricas e tracing não são luxo — são pré-requisito.

São três pilares que se complementam: logs dizem o que aconteceu, métricas dizem quanto e com que frequência, e o tracing distribuído mostra o caminho de uma requisição atravessando vários serviços. Somados a alertas que disparam antes do cliente perceber, eles são a diferença entre descobrir o problema pelo seu dashboard ou pelo telefone tocando às três da manhã.

Observabilidade colada depois é sempre pior e mais cara do que observabilidade pensada desde o início.

4. Design para degradação

Sistema resiliente sabe operar em modo reduzido. Quando uma dependência cai, ele não cai junto — degrada com elegância.

Isso significa decidir, de propósito, o que sacrificar para o núcleo continuar de pé: servir dados de um cache, desligar um recurso secundário por trás de uma feature flag, enfileirar o que pode esperar. O usuário talvez perca uma funcionalidade menor, mas o essencial continua funcionando. Degradar de forma controlada é muito melhor do que cair por inteiro.

5. Testar a falha de propósito

Se a primeira falha de rede do seu sistema for encontrada em produção, você não testou o sistema. Testou a sorte.

Falha é cenário de teste, não surpresa. Injeção de falhas e chaos engineering — derrubar uma dependência de propósito, introduzir latência, matar uma instância — revelam como o sistema se comporta antes que o cliente descubra por você. Testar o caminho feliz é fácil; resiliência se prova testando o caminho ruim, de preferência num ambiente controlado, antes que ele apareça sozinho no pior momento.

Resiliência não aparece no demo

Esse é o ponto que amarra tudo. Resiliência não aparece na demonstração. Ela aparece meses depois, sob carga real de produção — no momento em que "reiniciar" deixa de ser solução.

É por isso que essas cinco práticas não são enfeite de arquitetura. São o que garante que o sistema continua consistente quando algo dá errado — e, em produção, algo sempre dá errado.

Perguntas frequentes

O que é software resiliente?

É um software projetado para continuar funcionando (ou se recuperar rapidamente) quando algo falha — rede, dependência externa, pico de carga. O foco não é evitar toda falha, e sim controlar o comportamento do sistema quando ela acontece.

O que é idempotência?

É a garantia de que processar a mesma operação mais de uma vez produz o mesmo resultado que processá-la uma vez. É essencial em sistemas distribuídos, porque retries e reentregas de mensagens fazem a mesma requisição chegar repetida.

Retry sempre ajuda?

Não. Retry sem backoff e sem limite pode piorar a situação, transformando uma falha pontual em sobrecarga. Retry seguro exige backoff exponencial com jitter, limite de tentativas e um circuit breaker.

O que é chaos engineering?

É a prática de injetar falhas de propósito em um sistema — de forma controlada — para descobrir como ele se comporta sob condições adversas antes que essas condições apareçam sozinhas em produção.

Sua operação depende de software que não pode cair?

Na T4Tech, construímos integrações e sistemas pensados para o mundo real desde o primeiro requisito — não para o ambiente de testes. Se a sua operação depende de software que precisa aguentar carga real, vamos conversar.