01
O timeout não é uma margem de segurança, é uma declaração de desistência
A intuição por trás de um timeout generoso é que ele evita cortar uma requisição que ainda ia dar certo. Essa intuição trata o timeout como uma rede de proteção, e é por isso que os valores tendem a subir com o tempo: cada vez que alguém vê um erro de prazo esgotado em um caso legítimo, o reflexo é aumentar o número. O que essa leitura ignora é que o timeout não protege a requisição individual, ele protege o recurso compartilhado que a requisição está segurando enquanto espera. Uma conexão do pool, uma thread do servidor, um slot de concorrência do cliente HTTP, memória com o corpo da requisição carregado.
A conta que torna isso concreto é a Lei de Little aplicada ao pool de conexões. Se o serviço recebe cem requisições por segundo, cada uma segura uma conexão pelo tempo de resposta da dependência, e o pool tem cinquenta conexões, então o tempo máximo de resposta que o sistema tolera sem esgotar o pool é de meio segundo. Com timeout de trinta segundos, basta que a dependência fique lenta por alguns segundos para que todas as cinquenta conexões estejam ocupadas esperando, e a partir daí o serviço rejeita tráfego que não tem nada a ver com aquela dependência. O timeout generoso não deu chance à requisição lenta, ele derrubou todas as outras.
Reformulando: o timeout responde a uma pergunta de negócio, não de infraestrutura. A pergunta é a partir de quanto tempo essa resposta deixa de ter valor para quem pediu. Para uma consulta de saldo em tela de checkout, isso é algo entre um e dois segundos, porque depois disso o usuário já decidiu que o site quebrou. Para um job noturno de reconciliação, isso pode ser dez minutos. Os dois casos podem chamar exatamente a mesma dependência, e configurar o mesmo timeout para os dois é um erro nas duas direções ao mesmo tempo.
| Sintoma observado | Diagnóstico errado comum | Causa real | Ajuste correto |
|---|---|---|---|
| Pool de conexões esgotado sob dependência lenta | Pool pequeno demais | Timeout maior que o tempo de ocupação sustentável | Reduzir timeout para o p99 mais margem, não aumentar o pool |
| Erro de prazo esgotado em requisição que ia funcionar | Timeout curto demais | Timeout abaixo do p99 real da dependência | Medir a distribuição e recalibrar sobre o percentil |
| Dependência não se recupera depois do pico | Dependência sem capacidade | Retry do cliente multiplicando a carga durante a degradação | Orçamento de retry como fração do tráfego |
| Latência do usuário muito acima da soma das etapas | Rede lenta | Tentativas sequenciais consumindo o prazo do usuário | Prazo propagado com desconto a cada salto |
| Fatura da dependência sobe sem aumento de tráfego | Preço reajustado | Requisição paralela antecipada disparando sempre | Disparar a segunda cópia só acima do p95 |