Cache básico no Nginx: cache de proxy e controle de validade

Capítulo 11

Tempo estimado de leitura: 8 minutos

+ Exercício

O que é cache de proxy no Nginx (e quando usar)

Cache de proxy é quando o Nginx armazena respostas vindas de um upstream (sua API/aplicação) para reutilizá-las em requisições futuras. Isso reduz latência e carga no backend, principalmente em endpoints idempotentes (por exemplo, GET de leitura) e com respostas repetidas.

O cache de proxy do Nginx funciona como um “armazenamento” local (em disco e/ou memória de metadados) indexado por uma cache key. Quando chega uma requisição, o Nginx calcula a chave; se existir uma resposta válida associada, retorna do cache (HIT), caso contrário busca no upstream e pode armazenar (MISS).

Conceitos essenciais

  • Cache key: identifica unicamente uma resposta cacheada. Se a key não considerar algo importante (ex.: Authorization), você pode servir conteúdo errado para outro usuário.
  • Validade (TTL): por quanto tempo um item é considerado válido. Pode vir do upstream (headers) ou ser definido no Nginx (proxy_cache_valid).
  • Bypass/skip: condições para não usar o cache (bypass: não consultar; skip/no-store: não armazenar).
  • Condições para não cachear: respostas com cookies, com headers que proíbem cache, métodos não idempotentes, ou quando você decide explicitamente.

Passo a passo: configuração mínima de cache de proxy

1) Criar a área de cache com proxy_cache_path

Esta diretiva define onde o cache fica no disco, como ele é indexado e qual o nome da zona (metadados em memória) usada por proxy_cache.

proxy_cache_path /var/cache/nginx/api_cache levels=1:2 keys_zone=api_cache:20m max_size=2g inactive=30m use_temp_path=off;
  • /var/cache/nginx/api_cache: diretório no disco (garanta permissões para o usuário do Nginx).
  • levels=1:2: estrutura de subpastas para distribuir arquivos (evita milhões em um único diretório).
  • keys_zone=api_cache:20m: nome da zona + memória para metadados (não é o tamanho do cache em disco).
  • max_size=2g: limite aproximado do cache em disco.
  • inactive=30m: remove itens não acessados por 30 minutos (mesmo que ainda “válidos”).
  • use_temp_path=off: grava diretamente no diretório do cache (muitas vezes melhora I/O).

2) Aplicar o cache em um location de API idempotente

Exemplo de cache para um endpoint de leitura (GET /api/). A ideia é cachear apenas respostas bem-sucedidas e por um tempo curto, com possibilidade de bypass.

location /api/ {    proxy_pass http://api_upstream;    proxy_cache api_cache;    proxy_cache_methods GET HEAD;    proxy_cache_valid 200 1m;    proxy_cache_valid 404 10s;    proxy_cache_key $scheme$proxy_host$request_uri;    add_header X-Cache-Status $upstream_cache_status always;}

Pontos importantes:

Continue em nosso aplicativo e ...
  • Ouça o áudio com a tela desligada
  • Ganhe Certificado após a conclusão
  • + de 5000 cursos para você explorar!
ou continue lendo abaixo...
Download App

Baixar o aplicativo

  • proxy_cache api_cache; usa a zona definida em proxy_cache_path.
  • proxy_cache_methods GET HEAD; reforça que só métodos idempotentes entram no cache.
  • proxy_cache_valid define TTL por status HTTP (ex.: 200 por 1 minuto).
  • proxy_cache_key define a chave. Aqui usamos esquema + host do proxy + URI completa. Em APIs, muitas vezes você também precisa considerar query string (já está em $request_uri).
  • X-Cache-Status ajuda a validar HIT/MISS/BYPASS/EXPIRED etc.

Cache key: como evitar servir conteúdo errado

A cache key precisa refletir tudo que altera a resposta. Erros comuns:

  • Conteúdo por usuário: se a resposta muda por Authorization (token) e você não inclui isso na key, um usuário pode receber dados de outro. Em geral, não cacheie endpoints autenticados por usuário, ou use uma estratégia explícita.
  • Variação por header: se o upstream varia por Accept-Language, Accept etc., você pode precisar incluir esses headers na key.

Exemplo (use com cuidado) incluindo idioma:

proxy_cache_key $scheme$proxy_host$request_uri$http_accept_language;

Para endpoints com autenticação, uma prática segura é bypassar e não armazenar quando houver Authorization:

set $skip_cache 0; if ($http_authorization != "") { set $skip_cache 1; }

Bypass vs. Skip (não usar vs. não armazenar)

No Nginx, normalmente você controla isso com:

  • proxy_cache_bypass: quando verdadeiro, o Nginx não consulta o cache e vai ao upstream.
  • proxy_no_cache: quando verdadeiro, o Nginx não armazena a resposta no cache.

É comum usar a mesma condição para ambos, garantindo que requisições “sensíveis” não sejam servidas do cache e nem gravadas.

Exemplo prático: bypass por query string e por header

Você pode permitir um “modo debug” para forçar MISS, e também bypassar quando o cliente mandar Cache-Control: no-cache.

location /api/ {    set $skip_cache 0;    if ($arg_nocache = "1") { set $skip_cache 1; }    if ($http_cache_control ~* "no-cache|no-store") { set $skip_cache 1; }    if ($request_method !~ ^(GET|HEAD)$) { set $skip_cache 1; }    if ($http_authorization != "") { set $skip_cache 1; }    proxy_pass http://api_upstream;    proxy_cache api_cache;    proxy_cache_methods GET HEAD;    proxy_cache_bypass $skip_cache;    proxy_no_cache $skip_cache;    proxy_cache_valid 200 1m;    proxy_cache_valid 404 10s;    proxy_cache_key $scheme$proxy_host$request_uri;    add_header X-Cache-Status $upstream_cache_status always;}

Observações:

  • O bypass por método evita cachear POST, PUT, PATCH, DELETE.
  • O bypass por Authorization é uma proteção comum para não misturar respostas autenticadas.
  • O bypass por Cache-Control respeita a intenção do cliente (útil em debug e em alguns fluxos).

Condições comuns para não cachear (boas práticas)

1) Respostas com Set-Cookie

Em geral, respostas que setam cookie são específicas e não devem ser cacheadas. O Nginx pode evitar cache automaticamente em alguns casos, mas você pode ser explícito:

proxy_no_cache $upstream_http_set_cookie;

Isso impede armazenar quando o upstream envia Set-Cookie. Se você também quiser evitar servir do cache quando houver cookie na requisição:

proxy_cache_bypass $http_cookie;

2) Respeitar diretivas do upstream (ou sobrescrever)

O upstream pode enviar cabeçalhos que controlam cache, principalmente:

  • Cache-Control: ex.: max-age=60, no-cache, no-store, private.
  • Expires: data/hora de expiração (mais antigo, mas ainda usado).

Por padrão, o Nginx tende a respeitar diretivas que proíbem cache (como no-store) e pode usar informações de validade quando presentes. Porém, em muitos cenários você quer definir TTL no Nginx com proxy_cache_valid para ter previsibilidade.

3) Sobrescrever regras do upstream (quando você tem certeza)

Se o upstream não envia headers de cache adequados, você pode impor TTL no Nginx com proxy_cache_valid. Se o upstream envia Cache-Control: no-cache mas você quer cachear mesmo assim (com muito cuidado), você pode ignorar headers específicos com proxy_ignore_headers.

location /api/ {    proxy_pass http://api_upstream;    proxy_cache api_cache;    proxy_cache_valid 200 1m;    proxy_ignore_headers Cache-Control Expires;    add_header X-Cache-Status $upstream_cache_status always;}

Use isso apenas quando você controla o comportamento e entende o risco de servir dados desatualizados.

Validade (TTL) com proxy_cache_valid e cenários típicos

proxy_cache_valid permite TTL por código de status. Exemplos úteis:

proxy_cache_valid 200 302 1m; proxy_cache_valid 404 10s; proxy_cache_valid any 5s;
  • 200/302: cache curto para respostas “boas”.
  • 404: cache bem curto para reduzir carga em recursos inexistentes (evita martelar o backend).
  • any: fallback para outros status (use com cautela; muitas APIs não devem cachear 500).

Testes práticos: validando MISS/HIT com X-Cache-Status

1) Garantir que o header aparece sempre

Use always para o header aparecer mesmo em respostas de erro:

add_header X-Cache-Status $upstream_cache_status always;

Valores comuns:

  • MISS: não estava no cache, buscou no upstream e (se permitido) armazenou.
  • HIT: veio do cache.
  • BYPASS: bypass ativado, foi ao upstream.
  • EXPIRED: item existia mas expirou; buscou novamente.
  • STALE, UPDATING, REVALIDATED: podem aparecer em cenários avançados (stale/revalidação).

2) Testar com curl

Primeira requisição (tende a ser MISS):

curl -i http://localhost/api/products

Segunda requisição (tende a ser HIT dentro do TTL):

curl -i http://localhost/api/products

Forçar bypass via query string:

curl -i "http://localhost/api/products?nocache=1"

Forçar bypass via header do cliente:

curl -i -H "Cache-Control: no-cache" http://localhost/api/products

3) Validar que não cacheia quando há Authorization

curl -i -H "Authorization: Bearer test" http://localhost/api/products

Com as regras de $skip_cache, o esperado é X-Cache-Status: BYPASS e nenhuma gravação no cache.

Checklist rápido de segurança e previsibilidade

  • Cacheie apenas endpoints idempotentes (GET/HEAD) e com resposta compartilhável.
  • Defina uma cache key que reflita variações relevantes (URI, query string e, se necessário, headers).
  • Evite cache para conteúdo por usuário (especialmente com Authorization), a menos que você tenha uma estratégia explícita.
  • Use proxy_cache_valid para TTL previsível e ajuste por status.
  • Implemente bypass/skip para debug e para condições sensíveis (cookies, auth, métodos não idempotentes).
  • Teste sempre com X-Cache-Status para confirmar MISS/HIT/BYPASS.

Agora responda o exercício sobre o conteúdo:

Ao configurar cache de proxy no Nginx para uma API, qual combinação descreve corretamente a diferença entre bypass e no-store (skip) ao usar uma condição como $skip_cache?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

proxy_cache_bypass evita a consulta ao cache, forçando ida ao upstream. Já proxy_no_cache impede a gravação da resposta no cache quando a condição é verdadeira (ex.: requisições com Authorization).

Próximo capitúlo

Balanceamento básico no Nginx: upstream, round-robin e verificações simples

Arrow Right Icon
Capa do Ebook gratuito Nginx para Iniciantes: Servidor Web, Reverse Proxy e Balanceamento Básico
85%

Nginx para Iniciantes: Servidor Web, Reverse Proxy e Balanceamento Básico

Novo curso

13 páginas

Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.