Ao configurar uma política de cache HTTP no servidor Nginx, você orienta navegadores e proxies intermediários, como uma CDN, a armazenar ativos estáticos, como imagens e arquivos CSS e JS. Durante o período de validade, esses ativos são carregados diretamente de uma cópia local, sem necessidade de nova requisição ao servidor. Essa prática acelera o carregamento do site, reduz o consumo de largura de banda e diminui a carga no servidor.
Exemplos comuns de políticas de cache
Esta seção apresenta configurações de cache comuns aplicáveis diretamente ao arquivo de configuração do Nginx. Todos os exemplos utilizam a diretiva add_header ... always; para adicionar um cabeçalho de cache a todas as respostas, inclusive aquelas com código de status 304 Not Modified.
Caso de uso 1: Cache de longa duração para ativos estáticos
# Configure long-term caching for static assets
# - For filenames with a content hash (e.g., main.a1b2c3d4.js), a 1-year cache with 'immutable' is recommended.
location ~* "\.[a-f0-9]{8,}\.(css|js|png|jpg|jpeg|gif|svg|webp|ico|woff|woff2)$" {
# For assets with a hash generated by build tools: cache for 1 year, and instruct the browser to never revalidate.
add_header Cache-Control "public, max-age=31536003, immutable" always;
access_log off;
}
# - For filenames that are fixed and rarely change (e.g., logo.png), use a 30-day cache.
location ~* \.(css|js|png|jpg|jpeg|gif|svg|webp|ico|woff|woff2)$ {
# For generic static assets without a hash: cache for 30 days and allow both CDN and browser caching.
add_header Cache-Control "public, max-age=2592000" always;
access_log off;
}
Caso de uso 2: Cache para HTML e SPA
Páginas HTML, especialmente o arquivo de entrada de uma aplicação de página única (SPA) como index.html, são atualizadas frequentemente a cada novo deploy. Por isso, evite cache de longa duração para esses arquivos. Para melhor desempenho, permita que os navegadores façam cache, mas exija revalidação com o servidor antes de cada uso.
# For directly requested HTML files
location ~* \.html$ {
# Allows browser caching but requires revalidation with the server before each use.
# The 'private' directive prevents an intermediate proxy (like a CDN) from caching this response.
# The server must provide an ETag or Last-Modified header to support validation.
add_header Cache-Control "private, no-cache, must-revalidate" always;
}
Essa política exige que o servidor retorne um cabeçalho
ETagouLast-Modifiedpara permitir requisições condicionais pelo navegador. O Nginx fornece esses cabeçalhos para arquivos estáticos por padrão; portanto, nenhuma configuração adicional é necessária.Para impedir que proxies intermediários, como CDNs, armazenem conteúdo HTML em cache, utilize a diretiva "private". Isso garante que apenas o navegador do usuário final armazene a resposta.
Caso de uso 3: Sem cache para conteúdo dinâmico e sensível
Para conteúdo gerado dinamicamente ou sensível, como um endpoint de API, página de perfil de usuário ou página de pagamento, impeça que navegadores e proxies intermediários (como CDNs ou caches compartilhados) armazenem a resposta. Essa medida evita vazamentos de dados e inconsistências.
# Example: For dynamic PHP scripts (adjust the path based on your setup)
location ~ \.php$ {
# ... other PHP-FPM configurations ...
# Disable all caching: Browsers, proxies, and CDNs must not store the response.
# 'no-store' is the strictest cache control directive.
add_header Cache-Control "no-store" always;
}
Configuração de cache no cliente
Controle o cache do navegador adicionando os cabeçalhos Cache-Control e Expires às respostas HTTP.
Diretivas principais
-
Diretiva
expires: Define simultaneamente o cabeçalhoExpirese o valormax-agedo cabeçalhoCache-Control.Sintaxe:
expires [time|epoch|max|off];Exemplo:
expires 30d;(armazena o recurso em cache por 30 dias);expires -1;(força o cliente a validar o recurso com o servidor antes do uso, equivalente aCache-Control: no-cache, mas permite o armazenamento em cache).Observação: Recomenda-se a diretiva
add_header, pois oferece controle mais granular.
-
Diretiva
add_header: Adiciona um cabeçalho HTTP específico à resposta.Sintaxe:
add_header <name> <value> [always];Descrição do parâmetro
always: Por padrão, a diretivaadd_headeraplica-se apenas a respostas 2xx e 3xx. Para respostas304 Not Modified, o Nginx não adiciona cabeçalhos personalizados automaticamente. Embora os navegadores reutilizem a política de cache da resposta 200 inicial, adicione o parâmetroalwaysaos cabeçalhos de controle de cache para garantir clareza e compatibilidade. Isso assegura a aplicação dos cabeçalhos a todos os códigos de status de resposta.
Diretivas do Cache-Control
public: Qualquer cache pode armazenar a resposta, incluindo navegadores, CDNs e servidores proxy.private: Apenas o navegador do usuário final pode armazenar a resposta, não caches compartilhados como CDNs. Indicado para conteúdo com informações específicas do usuário.no-cache: Exige que o cliente envie uma requisição ao servidor para validar a cópia em cache antes de cada uso. Se o recurso não foi alterado, o servidor retorna304 Not Modified, permitindo que o cliente utilize o cache local e economize largura de banda.no-store: Proíbe navegadores e servidores proxy de armazenar qualquer parte da resposta. Adequado para dados altamente sensíveis.max-age=<seconds>: Define o tempo de vida (TTL) do cache em segundos.immutable: Informa ao navegador que o conteúdo do ativo não será alterado enquanto estiver em cache. Ideal para arquivos que incluem um hash de conteúdo no nome.
Implantar e verificar
Edite a configuração: Adicione o bloco
locationao blocoserverdo seu site. O arquivo de configuração geralmente está localizado em/etc/nginx/conf.d/ou/etc/nginx/sites-enabled/.-
Recarregue a configuração
sudo nginx -t && sudo nginx -s reload -
Verifique o cabeçalho de resposta: Utilize
curlpara conferir o cabeçalho de cache. Esse método ignora qualquer cache do navegador.curl -I http://your-domain.com/path/to/file.jsA resposta deve incluir os cabeçalhos esperados, como
Cache-Control: public, max-age=31536000. -
Verifique o comportamento
304(para políticas baseadas emno-cacheouETag): Teste com um cabeçalho de validação:ETAG=$(curl -I http://example.com/file.js 2>/dev/null | grep -i etag | cut -d' ' -f2 | tr -d '\r') curl -H "If-None-Match: $ETAG" -I http://example.com/file.js # Expects a 304 response -
Verifique no navegador
Abra as Ferramentas de Desenvolvedor e acesse o painel Network.
Marque a caixa de seleção Disable cache para visualizar o carregamento inicial. O status deve ser
200 OK.-
Desmarque a caixa de seleção e atualize a página:
Nenhuma requisição é feita ou é exibido
(from cache)→ acerto forte de cacheRetorna
304→ acerto condicional de cache
FAQ
Alterações não surtem efeito
Causa:
O comando
sudo nginx -s reloadnão foi executado.Um navegador, CDN ou servidor proxy está servindo uma resposta obsoleta.
Prioridade incorreta na correspondência do bloco
location.
Solução:
Utilize
curl -I http://your-urlpara verificar o cabeçalho de resposta diretamente no servidor.Verifique a ordem dos blocos
location. Correspondências por expressão regular (como~* \.(css|js)$) têm precedência sobre correspondências por prefixo (como/static/). Uma requisição pode ser processada pela regra errada devido a essa prioridade.
Conteúdo dinâmico armazenado em cache incorretamente
Causa: A expressão regular para ativos estáticos é muito abrangente (por exemplo, ~* \.js$ corresponde a /api/user.js).
Solução:
Restrinja o caminho:
location ~* ^/static/.*\.(css|js)$Garanta que o
locationpara interfaces dinâmicas, como/api/e\.php$, tenha prioridade de correspondência ou seja explicitamente excluído do cache.
Políticas de cache conflitantes
Causa: Vários blocos
locationcorrespondem à mesma requisição, mas apenas o primeiro tem efeito.-
Solução: Utilize um bloco
mappara consolidar políticas e definir dinamicamente a política de cache com base no tipo de conteúdo.# In the http block map $sent_http_content_type $cache_control { ~^image/ "public, max-age=2592000"; text/css "public, max-age=2592000"; application/javascript "public, max-age=2592000"; default "no-cache"; } # In the server block add_header Cache-Control $cache_control always;