Handshake: o custo invísivel das APIs modernas
Source: Dev.to
O que está acontecendo?
Quando localmente a API responde em 20 ms, os logs não apontam gargalos, o banco já foi otimizado e o código está limpo. Pronto para produção, porém, ela passa a responder com 400 ms. Voltamos imediatamente aos logs, revisamos o código, olhamos para o banco, e temos certeza de que o problema tem que estar ali.
O que geralmente esquecemos, ou simplesmente não percebemos, é que antes do primeiro byte ser enviado já foi pago um custo.
Cliente e servidor precisam se comunicar. A negociação dessa comunicação por segurança e confiabilidade gera um custo que é influenciado pela qualidade da rede, a distância entre as regiões envolvidas e o protocolo de transporte utilizado. Localmente esse custo é imperceptível, mas não conseguimos fugir dele em produção. Quando ignorado, ele se multiplica silenciosamente em arquiteturas modernas.
Caminho percorrido
Caso a resolução do DNS não esteja no cache, a requisição percorrerá um processo hierárquico:
- O cliente consulta os root servers, que indicam quais servidores são responsáveis pelo TLD.
- Os servidores de TLD apontam para os servidores autoritativos do domínio, que finalmente retornam o endereço IP.
Cada uma dessas etapas gera uma comunicação ida e volta e pode adicionar latência antes mesmo da conexão ser estabelecida.
Ainda antes de qualquer dado ser transmitido, o TCP precisa estabelecer uma conexão confiável entre cliente e servidor. Esse processo, chamado de three‑way handshake, exige no mínimo uma ida e volta pela rede.
Em conexões que exigem segurança, esse custo aumenta. Após o estabelecimento do TCP, ainda é necessário negociar segurança, e o TLS requer mais uma etapa de comunicação entre cliente e servidor.
O custo já foi pago. Não podemos eliminá‑lo, mas é possível amortizar ou reduzir seu impacto arquiteturalmente.
Redução de danos
Essa latência não é um problema de implementação, e sim uma consequência de decisões corretas sobre confiabilidade e segurança. Como não é possível eliminá‑la, a ideia é decidir quando, quantas vezes e onde esse custo será pago.
- Reutilização de conexões: com keep‑alive e connection pooling, o custo do DNS, TCP e TLS será pago uma única vez, enquanto múltiplas requisições trafegam pelo mesmo canal.
- HTTP/2: permite multiplexar várias requisições em uma única conexão, reduzindo o número de conexões necessárias. O ganho não está em tornar a rede mais rápida, mas em reduzir quantas vezes o custo inicial precisa ser pago.
- TLS session resumption: em conexões seguras, permite que cliente e servidor reutilizem informações de uma conexão TLS anterior, evitando repetir todo o handshake completo.
- Centralização da terminação TLS: colocar a terminação de TLS em load balancers ou API gateways muda onde esse custo acontece e impede que ele se espalhe de forma descontrolada entre serviços internos.
- HTTP/3 (QUIC): elimina a dependência do TCP e incorpora o TLS na camada de transporte, reduzindo o número de etapas necessárias antes do primeiro byte. Em cenários como mobile e conexões instáveis, essa diferença costuma ser decisiva.
- Evitar chamadas desnecessárias: cache, agregação de dados e redução de fan‑out não tornam o handshake mais rápido, mas evitam que ele ocorra.
Latência é o resultado de quantas vezes decidimos atravessar a rede. Quando o custo do handshake é ignorado, ele se multiplica. Quando tratado como parte da arquitetura, pode ser controlado, amortizado e, muitas vezes, deixado fora do caminho crítico.
Referências
- System Design – Protocolos e Comunicação de Rede
- Optimizing TLS over TCP to Reduce Latency – Cloudflare Blog
- SSL/TLS Recommender – Cloudflare Blog
- What is DNS? – Cloudflare Learning