trilha

System Design/05 - Reliability Patterns/Resiliency2 min

Retry

Perguntas-guia
  • Que problema isso resolve?
  • Quando usar / quando NÃO usar?
  • Qual o principal trade-off?
  • Como isso falha em produção?

Conceito

Repetir uma operação que falhou, apostando que a falha era transitória.

Quando repetir — e quando não

Repetir Não repetir
Timeout de rede 400 Bad Request
503 Service Unavailable 401 / 403
429 Too Many Requests (com Retry-After) 404 Not Found
Deadlock ou lock timeout 422 — dado inválido
Falha de conexão Erro de lógica

A regra: repetir 4xx (exceto 429) não adianta — o pedido está errado e continuará errado.

Backoff exponencial com jitter

for tentativa in range(3):
    try: return operacao()
    except TransitorioError:
        if tentativa == 2: raise
        espera = min(2 ** tentativa, 30) * random.uniform(0.5, 1.5)
        time.sleep(espera)

Jitter é a parte mais importante e a mais esquecida. Backoff sem jitter mantém os clientes sincronizados: todos esperam 1 s, depois 2 s, depois 4 s — juntos. O serviço recebe rajadas periódicas e nunca se recupera entre elas.

Trade-offs

Retry aumenta a chance de sucesso numa falha transitória e piora qualquer falha sistêmica — é a mecânica do Retry Storm. Como distinguir uma da outra em tempo real é difícil, a proteção prática é limitar o dano: teto de tentativas, retry budget (no máximo 10% do tráfego pode ser retry) e Circuit Breaker por cima.

O segundo risco é a multiplicação em cascata: se cada camada repete três vezes, quatro camadas encadeadas produzem 81 requisições para uma chamada original. A prática correta é repetir numa camada só, tipicamente a mais externa, e deixar as internas falharem rápido.

E a condição inegociável: retry só é seguro em operação idempotente. Repetir uma cobrança não idempotente cobra duas vezes — e o cliente não vai aceitar "foi um timeout" como explicação.

Vale lembrar que uma resposta perdida é indistinguível de uma requisição não processada. O cliente que repete não sabe se a primeira funcionou; só a idempotência torna a dúvida irrelevante (Idempotent Operations).

Exemplo prático

Uma chamada a um gateway de pagamento que sofre timeout.

Sem chave de idempotência, repetir é apostar: se a primeira tentativa chegou e só a resposta se perdeu, o cliente é cobrado duas vezes.

Com chave de idempotência, o retry é seguro:

POST /cobranca
Idempotency-Key: 7f3a-...

A segunda tentativa com a mesma chave devolve a resposta da primeira, sem cobrar de novo. É essa combinação — retry com backoff e jitter, sobre operação idempotente, com circuit breaker por cima — que torna a resiliência segura em vez de perigosa.

Relacionado


Parte de Resiliency · roadmap.sh/system-design

Buscar

Busca por título, seção e texto das notas