WebSockets versus SSE versus Long Polling — Escolha o padrão de tempo real certo antes de seu aplicativo de chat se desfazer
A maioria dos desenvolvedores opta por WebSockets sem pensar duas vezes. Esta análise de WebSockets, Server-Sent Events e polling prolongado aborda as verdadeiras diferenças — latência, comportamento de reconexão, complexidade da infraestrutura, bidirecionalidade — para que você possa escolher o padrão certo e parar de over-engineerizar sua feed de dados.
Você construiu um painel. Os usuários precisam de atualizações em tempo real. Você optou por WebSockets — porque é o que todos fazem. Agora você está debugando sessões "coladas" às 2 da madrugada porque seu balanceador de carga continua enviando clientes para o pod errado. Os dados que você está enviando? Um único número JSON a cada 10 segundos. WebSockets foram excessivos.
Isso acontece constantemente. Desenvolvedores tratam WebSockets como a solução padrão para tempo real, quando SSE ou polling prolongado teriam sido mais rápidos, mais escaláveis e mais baratos de operar. Aqui está como escolher realmente.
A Tabela de Decisão
Antes da análise aprofundada, segue a comparação completa. Use isso para tomar uma decisão, depois leia as seções abaixo se precisar de justificativas.
| Recurso | Long polling | Eventos Enviados pelo Servidor | WebSockets |
|---|---|---|---|
| Protocolo | HTTP/1.1 | HTTP/1.1+ (em blocos) | WS (upgrade HTTP) |
| Direção | O cliente apenas puxa | O servidor → o cliente apenas | Bidirecional completa |
| Suporte no navegador | Todos os navegadores | Todos os modernos (sem IE11) | Todos os modernos |
| Reconexão automática | Manual — você escreve o loop | Incorporado via EventSource | Manual ou via biblioteca |
| Amigável para CDN / proxy | Sim | Quase sempre (tempo de espera de monitoramento) | Não |
| Escalabilidade horizontal | Estável, trivial | Estável, trivial | Requer sessões "coladas" ou um broker de pub/sub |
| Complexidade da infraestrutura | Baixa — HTTP simples | Baixa — HTTP simples | Alta — conexões estatais, configuração do balanceador, broker |
| Latência | Intervalo de polling + viagem de retorno | Próximo ao tempo real | Próximo ao tempo real |
| APIs, microserviços, autenticação cross-domain | Atualizações de baixa frequência, infraestrutura antiga | Painéis, feeds, notificações | Chat, edição colaborativa, jogos |
Polling prolongado: O Trabalhador Inexpressivo
O polling prolongado não é "antigo" ou "errado" — é apenas HTTP. O cliente faz uma requisição, o servidor mantém aberta até haver algo para dizer (ou um tempo de espera acaba), o cliente recebe a resposta e imediatamente faz a próxima requisição. Repita.
Está disponível desde antes da existência de WebSockets e ainda funciona em milhões de aplicações em produção. O motivo: é apenas HTTP. Seu reverse proxy, CDN, balanceador de carga e monitoramento já entendem isso sem configuração. Sem sessões "coladas", sem upgrades de protocolo, sem infraestrutura WS-aware.
As desvantagens são reais. Cada "atualização" é um ciclo completo de requisição HTTP — cabeçalhos, sobrecarga TCP (a menos que seja HTTP/2), fila de requisições no lado do servidor. Sob alta concorrência, isso se torna caro no servidor. E o limite de latência é o tempo de viagem de cada polling, não a latência do evento em si. Se você está polling a cada 5 segundos e um evento ocorre no segundo 1, o usuário espera 4 segundos a mais.
Quando usá-lo: Sistemas legados onde adicionar uma camada de conexão persistente não vale a mudança na infraestrutura. Atualizações de baixa frequência (uma vez por minuto ou menos). Ambientes onde SSE é matado por proxies excessivamente exigentes. Polling que os clientes controlam explicitamente — verificações de status de tarefas, resultados de tarefas assíncronas.
Eventos Enviados pelo Servidor: O Que Todo Mundo Esquece
SSE é um padrão (Padrão HTML Ativo) que permite que um servidor envie uma stream de eventos de texto sobre uma única conexão HTTP persistente. O navegador trata automaticamente a reconexão. Você não escreve um loop de reconexão — o EventSource API reconecta com o último ID de evento que viu, então você pode continuar a stream após um problema de rede.
O formato da conexão é absurdamente simples:
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
id: 1
event: price-update
data: {"symbol":"BTC","price":67420}
id: 2
event: price-update
data: {"symbol":"ETH","price":3521}
Cada evento é texto simples com campos opcionais id, event, datae, e retry separados por linhas em branco. Você pode testar endpoints SSE diretamente com cURL — use o Construtor de Comandos cURL para construir a requisição com a cabeça correta (text/event-stream) e transmitir a resposta.
No lado do cliente:
const es = new EventSource('/api/events');
es.addEventListener('price-update', (e) => {
const payload = JSON.parse(e.data);
updateDashboard(payload);
});
es.onerror = () => {
// EventSource will auto-reconnect. You don't need to do anything here
// unless you want to log or update UI state.
};
O SSE tem uma limitação real: é apenas servidor → cliente. O cliente não pode enviar dados de volta pela mesma conexão — ações iniciadas pelo cliente vão por requisições HTTP normais. Para a maioria dos casos de painéis, notificações e feeds, isso está bem. Você não estava usando a direção cliente → servidor de qualquer forma.
O outro problema: alguns proxies bufferizam o corpo da resposta e apenas a transmitem após a conexão ser fechada, o que quebra completamente a streaming. O NGINX precisa proxy_buffering off. A versão gratuita do Cloudflare bufferiza SSE. Se sua infraestrutura tiver um proxy de buffer no meio e você não puder configurá-lo, o SSE não funcionará e você precisará de WebSockets ou polling prolongado.
Quando usá-lo: Painéis em tempo real, feeds de notificações, logs de atividade, streaming de respostas de IA (exatamente o que o API de ChatGPT usa), tickers de ações, rastreamento de logs de deploy/construção. Qualquer lugar onde o servidor tenha dados para enviar e o cliente não precise enviar de volta.
WebSockets: Quando São de Verdade Valor
WebSockets oferecem uma conexão persistente bidirecional sobre um único socket TCP. Após a handshake de upgrade HTTP, ambas as partes podem enviar mensagens marcadas a qualquer momento. A latência é a mais baixa possível em uma rede — sem nova requisição por mensagem, sem cabeçalhos em cada frame.
A desvantagem é que são estatais. O servidor precisa acompanhar cada conexão aberta. Isso cria imediatamente problemas em grande escala: os balanceadores de carga redirecionam por conexão (não por requisição), então você precisa de sessões "coladas" ou de um broker de pub/sub (Redis, etc.) para distribuir mensagens entre múltiplos servidores. Seu CDN não pode cachear tráfego de WebSockets. Seu reverse proxy precisa de configuração explícita para o upgrade. Seu monitoramento precisa entender os frames WS se quiser visibilidade no nível do payload.
Nenhum desses fatores é insuperável, mas é trabalho real. Quando você começa um projeto e avalia opções, "é apenas HTTP" versus "conexões WS estatais com uma camada de pub/sub Redis" é uma diferença significativa em termos de complexidade.
Os payloads de WebSockets são tipicamente JSON. Se você está debugando uma integração com WebSockets e precisa inspecionar ou formatar as mensagens, o Formatador JSON torna mais fácil ler payloads minificados na aba de rede do seu dev tools.
Quando usá-las: Aplicações de chat (bidirecional genuinamente — cada mensagem é iniciada pelo cliente). Edição colaborativa (Figma, Google Docs — múltiplos clientes escrevendo em um estado compartilhado). Jogos multijogador (sincronização de estado de alta frequência e baixa latência). Terminais de negociação financeira (latência sub-100ms em livros de ordens). Basicamente: qualquer coisa onde o cliente precise enviar dados frequentemente, e não apenas recebê-los.
O Problema de Escalabilidade que Ninguém Menciona Até que Seja Demasiado Tarde
O polling prolongado e o SSE são estatais na camada HTTP. Cada requisição pode chegar em qualquer instância do servidor. Sua história de escalabilidade é simples e é um ponto positivo: adicione mais instâncias, feito. O estado da conexão existe apenas durante a duração da conexão HTTP aberta, e os balanceadores de carga redirecionam livremente.
Os WebSockets são estatais. A conexão do cliente A está no servidor 1. Quando você quer enviar uma mensagem para o cliente A do servidor 2 (porque o evento originou lá), o servidor 2 precisa saber sobre essa conexão. A solução padrão é um broker de pub/sub — Redis pub/sub, Kafka, ou serviços gerenciados como Pusher ou Ably que abstraem tudo isso. Você constrói essa camada por si mesmo ou paga por ela.
O Pusher cobra $49/mês para 500 conexões simultâneas. O Ably é igualmente caro. Se seu "feature de tempo real" for um badge de notificação que atualiza quando alguém curtiu seu post, isso é uma grande quantia para SSE que você poderia hospedar gratuitamente ao lado de sua API existente.
As mudanças do HTTP/2 Alteram os Cálculos do Polling Prolongado
O polling prolongado clássico é uma requisição por conexão por tempo de espera ativo. Sob HTTP/2, a multiplexação significa múltiplos fluxos em uma única conexão TCP. A sobrecarga é menor. Isso não é uma razão para escolher o polling prolongado em vez de SSE, mas significa que a crítica de que "a sobrecarga do HTTP é cara" se aplica menos em 2024 do que em 2012, quando essas comparações foram escritas inicialmente.
Se você estiver com HTTP/2 de ponta a ponta (cliente para servidor, sem proxy intermediário que desclassifica), o polling prolongado escala melhor do que a maioria das benchmarks antigas sugerem.
Guia Rápido de Decisão
Pare de ler aqui se seu uso for compatível com uma dessas situações:
- Frequência de atualização < 1/minuto, infraestrutura antiga, semântica de polling simples: Polling prolongado. Não complice.
- O servidor envia dados, o cliente lê principalmente, infraestrutura padrão HTTP: SSE. Isso cobre 80% de "features de tempo real".
- O cliente envia dados frequentemente, a latência < 100ms importa, bidirecional verdadeiramente: WebSockets. Agora vale a complexidade.
- Você está usando streaming de IA (OpenAI, Anthropic, etc.): SSE — é exatamente o que seus APIs de streaming usam.
- Jogo multijogador ou editor colaborativo: WebSockets, ou um framework especializado (Liveblocks, PartyKit, etc.).
A resposta padrão não é WebSockets. É SSE — até que você tenha uma razão específica para que não seja suficiente. O número de aplicações em produção que realmente precisam de tempo real bidirecional completo é muito menor do que o número que em lugar, vale a pena adicionar uma verificação explícita no CI para capturar quaisquer arquivos que passarem. Um passo de duas linhas cobre a maioria dos casos: WebSockets. Essa diferença é dívida de engenharia acumulada às 2 da madrugada diante de uma configuração de balanceador de carga.
Instale nossas extensões
Adicione ferramentas de IO ao seu navegador favorito para acesso instantâneo e pesquisa mais rápida
恵 O placar chegou!
Placar é uma forma divertida de acompanhar seus jogos, todos os dados são armazenados em seu navegador. Mais recursos serão lançados em breve!
Ferramentas essenciais
Ver tudo Novas chegadas
Ver tudoAtualizar: Nosso ferramenta mais recente foi adicionado em 18 de junho de 2026
