ETag: o que é, mecanismo de cache e configuração do cabeçalho

Autor: IT Sectr Publicado: 2026-03-09 Tempo de leitura: 8 min

ETag (Entity Tag) é um cabeçalho HTTP que atribui um identificador único a uma versão de recurso no servidor, permitindo que o cliente verifique eficientemente a relevância dos dados em cache. Em uma solicitação repetida, o navegador ou aplicativo envia o ETag salvo, e o servidor o compara com o atual: se coincidirem, retorna um status 304 Not Modified sem corpo de resposta. De acordo com RFC 7232 (IETF, 2014), solicitações condicionais com ETag reduzem o volume de dados transferidos em até 95% para recursos solicitados com frequência. Isso torna o cabeçalho criticamente importante para o desempenho de aplicativos móveis.

Pontos principais

  • ETag — um cabeçalho HTTP com um identificador único de versão de recurso para solicitações condicionais e cache
  • Como funciona — o servidor gera um hash do conteúdo ou número de versão, o cliente o envia no cabeçalho If-None-Match
  • ETags fortes e fracos — fortes (conteúdo idêntico byte a byte) e fracos (conteúdo semanticamente equivalente, prefixo W/)
  • 304 Not Modified — resposta do servidor quando o ETag coincide, economizando tráfego e acelerando o carregamento
  • ETag vs Last-Modified — ETag é mais preciso (hash do conteúdo), Last-Modified é mais simples (data), juntos oferecem máxima eficiência

O que é ETag?

ETag (Entity Tag) é um cabeçalho de resposta HTTP que contém um identificador único para uma versão específica de um recurso. O servidor calcula o ETag com base no conteúdo do arquivo, seus metadados ou número de revisão e o envia ao cliente na resposta a uma solicitação GET. O cliente salva este identificador e em solicitações subsequentes ao mesmo recurso o envia no cabeçalho If-None-Match. Se o recurso não mudou, o servidor responde com 304 Not Modified e o cliente usa sua cópia em cache.

O formato do ETag é definido na RFC 7232 como uma string entre aspas: "33a64df551425fcc55e4d42a148795d9f25f89d4". O valor pode ser um hash SHA-1 do conteúdo do arquivo, um número de versão incremental, uma combinação de inode-número-tempo para arquivos estáticos ou um token arbitrário gerado pelo servidor. O único requisito é que o valor deve mudar quando o recurso mudar e não deve mudar se o recurso permanecer o mesmo.

ETag pertence aos mecanismos de solicitações condicionais (conditional requests) — uma das otimizações básicas do protocolo HTTP. Ao contrário de solicitações incondicionais, onde o servidor sempre retorna uma resposta completa, uma solicitação condicional permite que o cliente verifique a relevância do cache sem recarregar os dados. De acordo com o HTTP Archive (2025), cerca de 40% de todas as respostas HTTP são 304 Not Modified graças à configuração adequada de ETag e Last-Modified.

Onde o ETag é usado

ETag é usado em APIs REST para otimizar o carregamento de coleções de dados — se a lista de objetos não mudou, o cliente recebe 304 sem transferir todo o JSON. Para arquivos estáticos (CSS, JS, imagens), o ETag permite que CDNs e navegadores verifiquem eficientemente a validade do cache. Em aplicativos móveis, o ETag é crítico para a sincronização em segundo plano: o aplicativo verifica se os dados no servidor mudaram e baixa atualizações apenas quando necessário. Isso economiza tráfego e bateria do dispositivo.

Como funciona o ETag?

O ciclo completo do ETag consiste em quatro etapas. O servidor gera um ETag na primeira solicitação e o retorna no cabeçalho de resposta. O cliente salva o ETag junto com o recurso em cache. Em uma solicitação repetida, o cliente envia o cabeçalho If-None-Match com o valor do ETag salvo. O servidor compara o valor recebido com o ETag atual do recurso: se coincidirem, retorna 304 Not Modified com corpo vazio; se não coincidirem, retorna 200 OK com o novo recurso e novo ETag.

http
// Solicitação do cliente com If-None-Match
GET /api/users HTTP/1.1
Host: example.com
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

// Resposta do servidor — recurso não modificado
HTTP/1.1 304 Not Modified
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

Em um aplicativo móvel, este ciclo pode ser implementado através de um cliente HTTP com suporte a cache. OkHttp, por exemplo, gerencia automaticamente o ETag através do CacheInterceptor: ele salva o ETag da resposta e adiciona If-None-Match em solicitações repetidas. Ao receber 304, o OkHttp retorna os dados em cache. OkHttp suporta ETag sem configuração adicional — basta habilitar o cache através de OkHttpClient.Builder.cache().

Geração de ETag no servidor

O servidor pode calcular ETags de diferentes maneiras: através de hash MD5 ou SHA do conteúdo, através de um número de revisão do banco de dados (por exemplo, updated_at do MySQL), através de uma combinação de inode + mtime + tamanho para arquivos estáticos (Nginx gera ETags exatamente desta forma). Para APIs dinâmicas, o hash do conteúdo é o mais confiável: se a resposta JSON mudar mesmo que um campo, o ETag mudará. No entanto, calcular um hash a cada solicitação sobrecarrega a CPU — para sistemas de alta carga, é melhor usar um número de versão incremental.

ETags fortes e fracos

RFC 7232 define dois tipos de ETags: fortes (strong) e fracos (weak). Um ETag forte significa que duas representações do recurso são idênticas byte a byte — nem um único bit difere. Um ETag fraco (prefixo W/) garante apenas equivalência semântica: o conteúdo pode diferir no nível de serialização (espaços, ordem dos campos JSON), mas os dados são considerados os mesmos para o cliente. ETags fracos são marcados com o prefixo W/, por exemplo W/"1a2b3c".

A escolha do tipo de ETag depende dos requisitos de precisão da comparação. Para arquivos estáticos (CSS, JS, imagens), ETags fortes são preferíveis — se o arquivo mudou, o cliente deve obter a nova versão. Para APIs dinâmicas, onde o mesmo JSON pode ser serializado com ordem diferente de campos ou formatação, ETags fracos oferecem mais flexibilidade: o servidor gera o ETag com base nos dados de negócio, não na representação em string.

Tipo de ETagFormatoGarantiaAplicação
Strong (forte)"hash"Identidade byte a byteArquivos estáticos, recursos binários
Weak (fraco)W/"hash"Equivalência semânticaAPI JSON, páginas dinâmicas

Uma limitação dos ETags fracos: eles não podem ser usados com solicitações de intervalo (Range requests). Se o cliente solicitar parte de um arquivo, o servidor deve retornar um ETag forte para garantir que o fragmento corresponde ao recurso completo. ETags fracos não oferecem essa garantia. Em outros cenários, ETags fracos são seguros e recomendados para APIs.

ETag vs Last-Modified

ETag e Last-Modified são dois cabeçalhos HTTP para solicitações condicionais que são frequentemente usados juntos. Last-Modified indica a data da última modificação de um recurso e funciona com o cabeçalho If-Modified-Since. ETag fornece um identificador único de versão e funciona com If-None-Match. Cada um tem suas vantagens e limitações, e combiná-los oferece a máxima eficiência de cache.

Last-Modified é mais simples de implementar — o servidor obtém automaticamente a data do sistema de arquivos ou atualiza o campo updated_at no banco de dados. No entanto, a data tem precisão de segundos, o que é insuficiente para recursos que mudam várias vezes por segundo. Além disso, Last-Modified não distingue entre diferentes estados: se um arquivo for sobrescrito com a mesma versão, a data muda mas o conteúdo não, então o cliente recarregará dados idênticos.

ETag é mais preciso: ele muda apenas quando o conteúdo realmente muda. Se o servidor restaurar uma versão anterior de um backup, o ETag muda. Se um arquivo for sobrescrito com os mesmos dados, o ETag permanece o mesmo e o cliente não recarrega. O uso combinado é recomendado pela especificação HTTP: o servidor retorna ambos os cabeçalhos, o cliente envia If-None-Match e If-Modified-Since simultaneamente. Se pelo menos um cabeçalho indicar uma mudança, o servidor retorna um novo recurso.

Prioridade dos cabeçalhos

De acordo com a especificação, ETag tem prioridade sobre Last-Modified. Se o servidor receber If-None-Match, ele deve verificar apenas o ETag, ignorando If-Modified-Since. Isso evita condições de corrida: se o recurso mudou entre o envio do Last-Modified pelo cliente e a verificação no servidor, o ETag será o indicador mais recente. Na prática, os servidores geralmente verificam ambos os cabeçalhos, mas quando os resultados divergem, o ETag vence.

Implementação de ETag no servidor

A configuração do ETag depende do tipo de servidor. Nginx gera ETags para arquivos estáticos automaticamente com base em inode, mtime e tamanho. Apache usa o mecanismo FileETag. Para aplicações dinâmicas em Node.js, PHP, Python, Ruby, os ETags precisam ser gerados programaticamente — através de hash da resposta, número de versão dos dados ou combinação de parâmetros de solicitação.

go
func etagMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter,
        r *http.Request) {
        // Gerar ETag com base nos dados
        etag := generateETag(r.URL.Path)
        w.Header().Set("ETag", etag)

        // Verificar If-None-Match
        if r.Header.Get("If-None-Match") == etag {
            w.WriteHeader(http.StatusNotModified)
            return
        }
        next.ServeHTTP(w, r)
    })
}

Um middleware em Go intercepta a solicitação, gera um ETag para a URL solicitada (por exemplo, calcula um hash dos dados do cache ou banco de dados) e define o cabeçalho de resposta. Se o cliente enviou If-None-Match e ele coincide com o ETag atual, o servidor retorna 304 Not Modified imediatamente, sem chamar o manipulador principal. Em produção, deve-se adicionar cache dos ETags calculados por URL e parâmetros para reduzir a carga no servidor.

Problemas e armadilhas

Em uma configuração de múltiplos servidores (round-robin ou anycast), o ETag deve ser o mesmo em todos os nós para o mesmo recurso. Se o ETag for gerado com base no inode do arquivo e o site estiver implantado em vários servidores, os valores diferirão. A solução é usar um hash do conteúdo ou armazenamento centralizado de versões (Redis, etcd). O segundo problema é a compressão gzip: o Nginx altera o ETag quando a compressão está habilitada, o que pode causar respostas 304 redundantes. É necessário configurar gzip_vary on para sincronizar o ETag com o conteúdo comprimido.

Perguntas frequentes

O ETag pode ser o mesmo para recursos diferentes?

Sim, se o servidor não tiver explicitamente evitado isso. Um ETag não precisa ser globalmente único — ele é único dentro de uma URL específica. Para arquivos estáticos, colisões são improváveis ao usar um hash SHA, mas geradores personalizados podem produzir duplicatas.

Preciso configurar ETag para cada recurso?

ETag é mais eficaz para recursos que são solicitados repetidamente e raramente mudam: ativos estáticos, listas de API, configurações. Para páginas únicas que são carregadas uma vez (por exemplo, uma página de confirmação de pedido), o ETag não oferece vantagens.

Como o ETag funciona com CDN?

CDNs consideram o ETag em solicitações de origem para verificar a validade do cache. Se o ETag de um recurso na origem mudou, a CDN carrega a nova versão. Cloudflare e Fastly suportam ETag como um mecanismo padrão de invalidação de cache no nível de origem.

Um ETag pode ter mais de 255 caracteres?

RFC 7232 não limita o comprimento do ETag, mas servidores e proxies podem truncar ou ignorar valores excessivamente longos. Recomenda-se usar um hash de 20–40 caracteres ou uma combinação de identificador de versão e soma de verificação.

O que escolher: ETag ou Cache-Control?

Não são mecanismos mutuamente exclusivos. Cache-Control define a política de cache (quanto tempo armazenar, quem pode), enquanto ETag é um mecanismo de validação de recursos em cache. A configuração ótima inclui ambos os cabeçalhos juntos.

Resumo

  • ETag — um cabeçalho HTTP com um identificador único de versão de recurso para solicitações condicionais e cache eficiente
  • Princípio — o cliente envia If-None-Match com o ETag salvo, o servidor responde com 304 se coincidirem
  • ETags fortes — identidade byte a byte para arquivos estáticos, fracos — equivalência semântica para APIs
  • ETag é mais preciso que Last-Modified — rastreia o conteúdo, não a data, e muda apenas com modificações reais
  • Uso combinado com Last-Modified oferece máxima eficiência de cache
  • Lado do servidor — geração via hash do conteúdo, número de versão dos dados ou combinação de parâmetros
  • Recomendação — use ETag para todos os endpoints de API e recursos estáticos em aplicativos móveis

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também