Compare ZSTD, Brotli e GZIP para APIs: velocidade, taxa de compressão, custo de CPU e padrões práticos para payloads JSON e binários em produção.

A compressão de resposta de API significa que seu servidor codifica o corpo da resposta (frequentemente JSON) em um fluxo de bytes menor antes de enviá-lo pela rede. O cliente (navegador, app móvel, SDK ou outro serviço) então descomprime. Sobre HTTP, isso é negociado via cabeçalhos como Accept-Encoding (o que o cliente suporta) e Content-Encoding (o que o servidor escolheu).
A compressão traz basicamente três benefícios:
A troca é direta: compressão economiza banda, mas custa CPU (compressão/descompressão) e às vezes memória (buffers). Se vale a pena depende de onde está seu gargalo.
Compressão costuma brilhar quando as respostas são:
Se você retorna grandes listas JSON (catálogos, resultados de busca, análises), compressão é frequentemente um dos ganhos mais fáceis.
Compressão é geralmente um mau uso de CPU quando respostas são:
Ao escolher entre ZSTD vs Brotli vs GZIP para compressão de API, a decisão prática costuma se resumir a:
Todo o resto neste artigo é sobre equilibrar esses três para sua API e padrões de tráfego.
Todos os três reduzem o tamanho do payload, mas otimizam para diferentes restrições—velocidade, taxa de compressão e compatibilidade.
Velocidade do ZSTD: Ótimo quando sua API é sensível à latência de cauda ou seus servidores são limitados por CPU. Ele pode comprimir rápido o suficiente para que o overhead seja muitas vezes negligenciável frente ao tempo de rede—especialmente para respostas JSON médias a grandes.
Taxa do Brotli: Ganha quando a banda é o principal recurso (clientes mobile, egress caro, entrega via CDN) e as respostas são principalmente texto. Payloads menores podem valer a pena mesmo se a compressão demorar mais.
Compatibilidade do GZIP: Melhor quando você precisa do máximo suporte do cliente com mínimo risco de negociação (SDKs antigos, clientes embarcados, proxies legados). É uma base segura mesmo que não seja a preferida em desempenho.
Níveis de compressão são presets que trocam tempo de CPU por saída menor:
A descompressão costuma ser muito mais barata que compressão para os três, mas níveis muito altos ainda podem aumentar CPU/bateria do cliente—importante para mobile.
Compressão é frequentemente vendida como “respostas menores = APIs mais rápidas.” Isso é frequentemente verdade em redes lentas ou caras—mas não é automático. Se a compressão adicionar tempo suficiente de CPU no servidor, você pode acabar com requisições mais lentas apesar de menos bytes na rede.
Ajuda separar dois custos:
Uma alta taxa de compressão pode reduzir o tempo de transferência, mas se a compressão adicionar (digamos) 15–30 ms de CPU por resposta, você pode perder mais tempo do que ganha—especialmente em conexões rápidas.
Sob carga, compressão pode prejudicar p95/p99 mais que p50. Quando o uso de CPU sobe, requisições enfileiram. Enfileiramento amplifica pequenos custos por requisição em grandes atrasos—a latência média pode ficar bem, mas os usuários mais lentos sofrem.
Não adivinhe. Rode um teste A/B ou rollout gradual e compare:
Teste com padrões de tráfego e payloads realistas. O “melhor” nível de compressão é o que reduz o tempo total, não apenas bytes.
Compressão não é “de graça”—ela desloca trabalho da rede para CPU e memória em ambas as pontas. Em APIs, isso aparece como maior tempo de tratamento de requisições, picos de memória e às vezes lentidão no cliente.
A maior parte da CPU é gasta comprimindo respostas. Compressão encontra padrões, constrói estado/dicionários e escreve a saída codificada.
A descompressão é tipicamente mais barata, mas ainda relevante:
Se sua API já é limitada por CPU (servidores de aplicação ocupados, autenticação pesada, queries caras), ligar compressão em nível alto pode aumentar a latência de cauda mesmo que os payloads encolham.
Compressão pode aumentar o uso de memória de várias formas:
Em ambientes conteinerizados, picos maiores de memória podem resultar em mais OOM kills ou limites mais apertados que reduzem a densidade.
Compressão adiciona ciclos de CPU por resposta, reduzindo o throughput por instância. Isso pode disparar autoscaling mais cedo, elevando custos. Um padrão comum: banda cai, mas gasto de CPU sobe—então a escolha certa depende de qual recurso é escasso para você.
Em mobile ou dispositivos de baixa potência, descompressão compete com renderização, execução de JavaScript e bateria. Um formato que economiza alguns KB mas demora mais para descomprimir pode parecer mais lento, particularmente quando “tempo até dados utilizáveis” importa.
Zstandard (ZSTD) é um formato moderno projetado para entregar boa taxa de compressão sem desacelerar sua API. Para muitas APIs ricas em JSON, é um forte “padrão”: respostas significativamente menores que GZIP com latência similar ou menor, além de descompressão muito rápida nos clientes.
ZSTD é mais valioso quando você se importa com o tempo ponta a ponta, não apenas bytes mínimos. Ele tende a comprimir rápido e descomprimir extremamente rápido—útil para APIs onde cada milissegundo de CPU compete com o tratamento da requisição.
Também se sai bem em uma ampla gama de tamanhos de payload: JSON pequeno a médio frequentemente vê ganhos, enquanto respostas grandes podem se beneficiar ainda mais.
Para a maioria das APIs, comece com níveis baixos (comumente 1–3). Eles frequentemente oferecem a melhor troca latência/tamanho.
Use níveis mais altos somente quando:
Uma abordagem pragmática é um padrão global baixo e aumentar seletivamente o nível para alguns endpoints de “resposta grande”.
ZSTD suporta streaming, o que pode reduzir pico de memória e começar a enviar dados mais cedo para respostas grandes.
O modo dicionário pode ser um grande ganho para APIs que retornam muitos objetos similares (chaves repetidas, esquemas estáveis). É mais efetivo quando:
Suporte no servidor é direto em muitas stacks, mas compatibilidade do cliente pode decidir. Alguns clientes HTTP, proxies e gateways ainda não anunciam ou aceitam Content-Encoding: zstd por padrão.
Se você atende consumidores terceiros, mantenha um fallback (geralmente GZIP) e habilite ZSTD apenas quando Accept-Encoding claramente o incluir.
Use compressão de resposta quando as respostas forem forte em texto (JSON/GraphQL/XML/HTML), médias a grandes, e seus usuários estiverem em redes lentas/caras ou você pagar custos significativos de egresso. Ignore (ou use um limiar alto) para respostas pequenas, mídia já comprimida (JPEG/MP4/ZIP/PDF) e serviços limitados por CPU onde trabalho extra por requisição vai prejudicar p95/p99 de latência.
Porque ela troca largura de banda por CPU (e às vezes memória). O tempo de compressão pode atrasar quando o servidor começa a enviar bytes (TTFB) e, sob carga, amplifica filas—frequentemente prejudicando a latência de cauda mesmo que a latência média melhore. A configuração “melhor” é a que reduz o tempo de ponta a ponta, não apenas o tamanho do payload.
Uma prioridade prática para muitas APIs é:
zstd primeiro (rápido, boa taxa)br (frequentemente o menor para texto, pode custar mais CPU)gzip (maior compatibilidade)Sempre baseie a escolha final no que o cliente anuncia em , e mantenha um fallback seguro (geralmente ou ).
Comece baixo e meça.
Use um limiar mínimo de tamanho de resposta para não queimar CPU com payloads minúsculos.
Faça tuning por endpoint comparando bytes poupados vs tempo de servidor adicionado e o impacto na latência p50/p95/p99.
Concentre-se em tipos de conteúdo estruturados e repetitivos:
A compressão deve seguir a negociação HTTP:
Accept-Encoding (por exemplo, zstd, br, gzip)Content-Encoding suportadoSe o cliente não enviar , a resposta mais segura é tipicamente . Nunca retorne que o cliente não anunciou, ou você arrisca falhas no cliente.
Adicione:
Vary: Accept-Encoding
Isso evita que CDNs/proxies façam cache (por exemplo) de uma resposta gzip e a sirvam incorretamente a um cliente que não pediu ou não consegue decodificar gzip (ou zstd/br). Se você suportar múltiplas codificações, esse cabeçalho é essencial para cache correto.
Falhas comuns:
Execute como um recurso de performance:
Accept-EncodinggzipidentityNíveis mais altos normalmente dão ganhos decrescentes e podem aumentar CPU e piorar p95/p99.
Uma abordagem comum é habilitar compressão apenas para valores de Content-Type do tipo texto e desativá-la para formatos já comprimidos conhecidos.
Accept-EncodingContent-EncodingContent-Encoding diz gzip mas o corpo não está gzip)Accept-Encoding)Content-Length incorreto ao fazer streaming/compressãoAo depurar, capture cabeçalhos brutos de resposta e verifique a descompressão com uma ferramenta/cliente conhecido.
Se a latência de cauda subir sob carga, reduza o nível, aumente o limiar ou troque para um codec mais rápido (frequentemente ZSTD).