DevGuideTK
← Trilha Backend

TCP, UDP e IP

As camadas de transporte abaixo do HTTP, e a troca entre entrega garantida e baixa latência.

Raramente um backend escolhe entre TCP e UDP: as bibliotecas escolhem por ele. As decisões que ficam com o desenvolvedor são outras: como reaproveitar conexões, quanto tempo esperar por elas, como mantê-las vivas e, quando houver um protocolo próprio, como delimitar as mensagens.

Quando cada transporte faz sentido

SituaçãoTransportePor quê
APIs, banco de dados, filas, cacheTCPPrecisam de tudo, em ordem
Arquivos e transferências grandesTCPEntrega garantida, com controle de congestionamento
Consultas de DNSUDP, com TCP para respostas grandesUma pergunta curta; repetir é mais barato que abrir conexão
Voz, vídeo, jogos em tempo realUDP, ou WebRTC sobre UDPDado atrasado não serve; melhor perder do que esperar
Métricas enviadas em grande volumeUDP (como no StatsD)Perder uma amostra é aceitável; não travar a aplicação é essencial
Web para usuários finaisHTTP/3 sobre QUIC, sobre UDPConexões mais rápidas e sem bloqueio por perda, tratado na borda

Reaproveitar conexões

Abrir uma conexão TCP custa uma ida e volta; com TLS, duas ou três. Reaproveitar elimina esse custo de todos os pedidos depois do primeiro.

OndeComo reaproveitar
Cliente HTTPUma instância compartilhada do cliente, com keep-alive ligado
Banco de dadosPool de conexões, criado uma vez na inicialização
Redis e filasUm cliente por processo, compartilhado
Entre serviços com muito tráfegoHTTP/2 ou gRPC, que multiplexam vários pedidos numa conexão

Conexões reaproveitadas trazem dois cuidados:

  • Conexões ociosas morrem em silêncio. Balanceadores, firewalls e NATs fecham conexões paradas há alguns minutos sem avisar as pontas. O próximo pedido numa conexão dessas falha. Bons pools validam ou descartam conexões ociosas antigas.
  • Conexões muito antigas ficam presas ao destino antigo. Uma conexão aberta continua falando com o endereço resolvido quando foi criada, mesmo que o DNS mude. O tópico de DNS mostra como limitar a idade das conexões.

Tempos limite

O TCP espera muito por padrão. Uma tentativa de conexão a um endereço que não responde pode levar mais de um minuto até desistir, e uma conexão aberta pode ficar esperando dados para sempre.

Tempo limiteO que limitaValor de partida
ConexãoQuanto esperar o handshake completar1 a 5 segundos dentro da mesma rede
LeituraQuanto esperar por dados numa conexão abertaConforme o tempo esperado da operação
Total do pedidoO pedido inteiro, do início ao fimO que o usuário ou o serviço chamador tolera
OciosidadeQuanto uma conexão parada fica no poolMenor que o limite do balanceador ou firewall no caminho

Sem tempo limite de conexão, um serviço que caiu sem fechar as conexões faz cada chamada esperar o tempo do sistema operacional, e as threads ou conexões do pool se esgotam esperando.

Manter a conexão viva

O keepalive do TCP envia pequenos pacotes numa conexão ociosa para descobrir se a outra ponta ainda existe, e para que os equipamentos no caminho não a considerem abandonada.

ConfiguraçãoO que fazPadrão típico no Linux
Tempo ocioso antes do primeiro testeQuanto esperar sem tráfego2 horas
Intervalo entre testesEspaço entre as tentativas75 segundos
Número de testesQuantas falhas até fechar9

O padrão de duas horas é longo demais para quase todo ambiente de nuvem, onde balanceadores costumam fechar conexões ociosas em minutos. Drivers de banco, clientes HTTP e bibliotecas de fila costumam permitir ligar o keepalive com tempos menores, ou têm o seu próprio mecanismo de verificação.

Protocolos próprios sobre TCP

Antes de criar um protocolo próprio sobre TCP, confira se HTTP, gRPC ou WebSocket resolvem: eles já tratam delimitação de mensagens, tempos limite, compressão e ferramentas de depuração. Se for mesmo necessário:

DecisãoOpções
DelimitaçãoTamanho antes dos dados (mais robusto, aceita qualquer conteúdo) ou delimitador (mais simples, exige escapar o delimitador)
Tamanho máximoSempre limitar: um tamanho anunciado de 4 GB não pode virar uma alocação de 4 GB
LeituraAcumular bytes até ter uma mensagem completa, nunca tratar uma leitura como uma mensagem
Tempo limiteDe leitura e de ociosidade, para que clientes lentos ou mortos não prendam o servidor

Resumo da decisão

  1. Transporte: TCP para quase tudo no backend; UDP para tempo real, DNS e telemetria; HTTP/3 na borda.
  2. Conexões: reaproveitar sempre, com pool e cliente compartilhado.
  3. Tempos limite: de conexão, de leitura e total, em todo cliente.
  4. Conexões ociosas: validar ou descartar antes que o caminho as feche.
  5. Protocolo próprio: só se HTTP, gRPC ou WebSocket não servirem, com delimitação, tamanho máximo e tempos limite.

O próximo nível mostra um servidor TCP que lê mensagens delimitadas do jeito certo nas cinco linguagens, e ferramentas para ver as conexões de perto.

Prompts para aprofundar

Ao abrir no ChatGPT ou no Claude, o prompt é enviado ao serviço escolhido pela URL e também fica copiado na sua área de transferência.

  • TCP, UDP ou QUIC para o meu caso

    Quero entender quando faz sentido usar cada transporte.
    
    Compare TCP, UDP e QUIC: garantias, custo de conexão, comportamento com perda de pacotes, controle de fluxo e de congestionamento, e suporte em proxies e firewalls.
    
    Depois me apresente oito situações, uma por vez, e pergunte qual transporte eu usaria e por quê:
    1. Uma API REST entre microsserviços.
    2. Chamadas de voz num aplicativo.
    3. Envio de métricas da aplicação em grande volume.
    4. Transferência de arquivos grandes.
    5. Um jogo multijogador em tempo real.
    6. Consultas de DNS.
    7. Um site acessado por celular em redes instáveis.
    8. Replicação entre dois bancos de dados.
    
    Corrija cada resposta e explique o que daria errado com a alternativa.
  • Configurar conexões e tempos limite

    Quero configurar corretamente as conexões de rede da minha aplicação: reaproveitamento, tempos limite e keepalive.
    
    Pergunte qual linguagem eu uso, quais clientes de rede a aplicação tem (HTTP, banco, Redis, filas) e onde ela roda (nuvem, Kubernetes, atrás de qual balanceador).
    
    Para cada cliente, explique:
    1. Como garantir o reaproveitamento de conexões.
    2. Quais tempos limite configurar (conexão, leitura, total) e valores de partida.
    3. O que acontece com conexões ociosas no meu ambiente e como evitar falhas por conexões fechadas em silêncio.
    4. Se vale ligar o keepalive do TCP e com quais tempos.
    
    Termine com uma tabela de configuração para cada cliente, com os valores recomendados e o motivo de cada um.
  • Criar ou não um protocolo próprio

    Estou pensando em criar um protocolo próprio sobre TCP para comunicação entre dois sistemas. Quero avaliar se vale a pena.
    
    Pergunte o que os sistemas trocam, em que volume e com quais requisitos de latência.
    
    Depois:
    1. Avalie se HTTP, gRPC ou WebSocket resolveriam, e o que cada um já oferece pronto.
    2. Se um protocolo próprio for mesmo necessário, ajude a desenhá-lo: delimitação das mensagens, tamanho máximo, versão do protocolo, tratamento de erros, tempos limite e encerramento.
    3. Liste os ataques e falhas que um protocolo próprio precisa tratar, como tamanho anunciado gigante, envio lento e conexões abertas em excesso.
    4. Diga como testar o protocolo, inclusive com latência e perda simuladas.