trilha

System Design/02 - Componentes/Caching2 min

Refresh Ahead

Perguntas-guia
  • Que problema isso resolve?
  • Quando usar / quando NÃO usar?
  • Qual o principal trade-off?
  • Como isso falha em produção?

Conceito

O cache atualiza a entrada antes de ela expirar, de forma proativa, para que o usuário nunca encontre um miss.

TTL = 60s, fator de refresh = 0,75

t=0    escrito no cache
t=45   alguém lê → serve do cache E dispara refresh em background
t=60   expiraria — mas já foi renovado

O gatilho usual: um acesso ocorre depois de 75% do TTL ter passado. A leitura é servida do cache imediatamente, e a atualização acontece fora do caminho da requisição.

Trade-offs

Ganha Perde
Usuário nunca paga o custo do miss Prevê errado: atualiza o que ninguém vai pedir
Elimina o cache stampede Carga constante na fonte
Latência previsível (sem cauda) Complexidade a mais

A eficácia depende inteiramente da previsibilidade do acesso. Para chaves consistentemente populares, refresh ahead é quase perfeito: elimina o miss e o stampede de uma vez. Para chaves de acesso esporádico, ele desperdiça — atualiza entradas que expirariam sem ninguém notar.

Daí a regra: aplique a poucas chaves, as mais quentes, não ao cache inteiro. Refresh ahead global transforma cache numa fonte de carga permanente sobre o banco.

O primo mais simples e frequentemente melhor é stale-while-revalidate: serve o dado vencido imediatamente e revalida em background. A diferença é sutil — SWR reage ao vencimento, refresh ahead se antecipa a ele — e SWR não desperdiça atualização em chave fria, porque só atualiza o que é realmente pedido.

Exemplo prático

Cotação de moeda exibida na home, consultada por milhares de usuários por minuto e vinda de uma API externa lenta (300 ms) e com limite de requisições.

Com Cache-Aside e TTL de 60 s: a cada minuto, o primeiro usuário espera 300 ms — e, sob concorrência, dezenas de requisições disparam a chamada externa simultaneamente, ameaçando o rate limit.

Com refresh ahead: aos 45 s uma atualização é disparada em background. Nenhum usuário espera, e a API externa recebe exatamente uma chamada por minuto.

O desperdício potencial — atualizar a cotação de madrugada, quando ninguém acessa — é irrelevante aqui, porque a chave é uma só e sempre quente. Se fossem 5.000 cotações de acesso irregular, a conta se inverteria.

Relacionado


Parte de Caching · roadmap.sh/system-design

Buscar

Busca por título, seção e texto das notas