Todos os produtos
Search
Central de documentação

CDN:Nginx HTTP cache policy

Última atualização: Sep 06, 2026

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;
}
Nota
  • Essa política exige que o servidor retorne um cabeçalho ETag ou Last-Modified para 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çalho Expires e o valor max-age do cabeçalho Cache-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 a Cache-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 diretiva add_header aplica-se apenas a respostas 2xx e 3xx. Para respostas 304 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âmetro always aos 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 retorna 304 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

  1. Edite a configuração: Adicione o bloco location ao bloco server do seu site. O arquivo de configuração geralmente está localizado em /etc/nginx/conf.d/ ou /etc/nginx/sites-enabled/.

  2. Recarregue a configuração

    sudo nginx -t && sudo nginx -s reload
  3. Verifique o cabeçalho de resposta: Utilize curl para conferir o cabeçalho de cache. Esse método ignora qualquer cache do navegador.

    curl -I http://your-domain.com/path/to/file.js

    A resposta deve incluir os cabeçalhos esperados, como Cache-Control: public, max-age=31536000.

  4. Verifique o comportamento 304 (para políticas baseadas em no-cache ou ETag): 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
  5. Verifique no navegador

    1. Abra as Ferramentas de Desenvolvedor e acesse o painel Network.

    2. Marque a caixa de seleção Disable cache para visualizar o carregamento inicial. O status deve ser 200 OK.

    3. Desmarque a caixa de seleção e atualize a página:

      1. Nenhuma requisição é feita ou é exibido (from cache) → acerto forte de cache

      2. Retorna 304 → acerto condicional de cache

FAQ

Alterações não surtem efeito

Causa:

  1. O comando sudo nginx -s reload não foi executado.

  2. Um navegador, CDN ou servidor proxy está servindo uma resposta obsoleta.

  3. Prioridade incorreta na correspondência do bloco location.

Solução:

  1. Utilize curl -I http://your-url para verificar o cabeçalho de resposta diretamente no servidor.

  2. 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:

  1. Restrinja o caminho: location ~* ^/static/.*\.(css|js)$

  2. Garanta que o location para 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 location correspondem à mesma requisição, mas apenas o primeiro tem efeito.

  • Solução: Utilize um bloco map para 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;