← Back to list

Perda de Query Strings no AWS CloudFront + S3? Veja o por que acontece e como resolver

Se você chegou a esse artigo, há grandes chances de estar tendo problemas com Query Strings relacionados ao CloudFront/S3. Pois bem, eu…

Everton Fonseca · 2025-03-06 13:40 · 0 claps · 7.3 min read
#cloudfront #querystring #cloudfront-functions #lambda-edge #s3
Open on Medium ↗
Wiki topics: GEN · Genomics & Sequencing ☁️ · DevOps & Cloud

Perda de Query Strings no AWS CloudFront + S3? Veja o por que acontece e como resolver

Se você chegou a esse artigo, há grandes chances de estar tendo problemas com Query Strings relacionados ao CloudFront/S3. Pois bem, eu também passei por isso e o que parecia ser algo simples de se resolver num primeiro momento, se tornou uma jornada de muito aprendizado e descobertas de como alguns serviços AWS e suas features funcionam “por debaixo dos panos”. Espero que algum aprendizado das fases dessa jornada possa vir a ajudar.

O CloudFront e a perda das Query Strings

Introdução

Realizamos a migração de um site com alto volume de acessos para o CloudFront + S3. Esse site é um componente essencial para campanhas de marketing digital, sendo o mesmo uma etapa de funil para diversos anúncios e parte fundamental para o rastreamento de conversões. A princípio, a migração parecia simples e direta, mas logo percebemos um problema crítico: as query strings passadas nas requests estavam sendo perdidas.

Essas query strings são fundamentais para o time de marketing, pois carregam informações como por exemplo:

  • utm_source: Identifica a origem do tráfego (ex.: Google, Facebook, E-mail, etc.).
  • utm_campaign: Associa o acesso a uma campanha específica.
  • utm_medium: Indica o tipo de tráfego (ex.: CPC, orgânico, referência).

Sem essas informações, o rastreamento dos acessos se tornava impossível, comprometendo as análises de desempenho das campanhas.

O Problema: CloudFront e a Perda de Query Strings

Após investigarmos o problema, identificamos que as query strings desapareciam quando as URLs eram acessadas sem uma / no final dos paths.

Por exemplo, quando um usuário acessava:

https://meusite.com/promocao?utm_source=google

O esperado era que essa query string fosse preservada, mas o que acontecia era:

https://meusite.com/promocao

A query string simplesmente sumia.

Isso era um problema grave, pois grande parte do tráfego vinha de anúncios e campanhas que usavam esses parâmetros para rastrear a origem do acesso.

Por que isso acontecia?

Após algumas pesquisas e testes, constatamos que o problema estava na forma como o Amazon S3 trata objetos e URLs. Diferente de servidores tradicionais (como Apache ou Nginx), o S3 funciona como um armazenamento de objetos, onde cada arquivo precisa ter um nome exato.

Se nosso site possui um arquivo chamado promocao/index.html, o acesso correto seria:

https://meusite.com/promocao/

Pois dessa forma, passando a / no fim da url o S3 entende que o path da url é um prefixo do objeto root configurado no S3. Mas quando um usuário acessa sem a / no final, o CloudFront tenta buscar um objeto chamado "promocao", que não existe no S3. O que acontece é que o CloudFront redireciona para a versão correta (/promocao/), dado que /promocao se trata de um prefixo do objeto /promocao/index.html mas nesse redirecionamento para o objeto correto, as query strings eram perdidas.

Agora que entendemos que o problema é causado pela fata da / no final da url path, vamos explorar a primeira solução implementada e seu impacto nos custos.

A primeira solução e o aumento de custos

Agora vamos falar sobre a primeira solução que implementamos e como isso resolveu o problema porém levou a um aumento inesperado nos custos do CloudFront.

CloudFront Function + Forward Query Strings

Ao pesquisar bastante sobre o problema, encontramos vários posts e artigos que convergiam para o mesmo caminho, abordando a implementação de duas configurações/implementações:

  1. CloudFront Function para forçar a Barra /
  • Criamos uma CloudFront Function que foi associada à Viewer Request do CloudFront para verificar se as URLs das requests recebidas terminam sem / e ajustar para o formato esperado pelo S3, com a / no final, garantindo assim que o root object seja devidamente chamado, evitando redirects por parte do S3 na busca de objetos e consequentemente evitando a perda das query strings.
function handler (event) {
    var request = event.request;
    var uri = request.uri;

    // Se a URI não contém extensão e não termina com '/', adicionamos '/'
    if( !uri.includes('.') && !uri.endsWith('/') ) {
        request.uri = uri + '/'
    }

    return request;
};
  1. Habilitação da opção “Forward Query Strings”
  • No CloudFront, ativamos a opção “Forward Query Strings” para garantir que os parâmetros de rastreamento fossem preservados ao encaminhar a requisição para a origem.

Com essas alterações, o problema foi resolvido e as query strings começaram a ser preservadas corretamente. Mas então, percebemos algo preocupante: o custo do CloudFront aumentou de forma considerável.

O Que Causou o Aumento de Custos?

De inicio imaginamos que o responsável pelo aumento de custos fosse a CloudFront Function, devido ao fato de a mesma estar associada à Viewer Request e ser executada a cada nova request que chegava ao CloudFront.

Estágios de request/response onde a function pode ser triggada no cloudfront

Estágios de request/response onde a function pode ser triggada no cloudfront

Porém após alguns ajustes e testes constatamos que a principal razão para esse aumento no custo foi a opção “Forward Query Strings” habilitada. No incio isso não fazia muito sentido, pois tínhamos em mente que ao habilitar essa opção, o que ela faria seria somente permitir a passagem das query strings do CloudFront para a origem(S3). Após algumas pesquisas para entender o que de fato essa feature faz, descobrimos que o comportamento dela não era nada disso. Aqui está o que de fato aconteceu:

  1. Cache fragmentado
  • Quando o CloudFront não encaminha query strings, ele armazena apenas uma única versão de cada página no cache.
  • Mas ao ativar “Forward Query Strings”, o cache passou a armazenar uma cópia separada para cada combinação de query string.

Por exemplo, antes da mudança, https://meusite.com/promocao era armazenado uma única vez no cache. Depois da mudança, cada variação gerava uma nova entrada no cache:

https://meusite.com/promocao/?utm_source=google
https://meusite.com/promocao/?utm_source=facebook
https://meusite.com/promocao/?utm_source=email
https://meusite.com/promocao/?utm_source=google&utm_campaign=blackfriday

Isso fez com que o cache ficasse altamente fragmentado, reduzindo a taxa de acerto do cache (cache hit ratio).

2. Aumento de requisições para a origem

  • Com o cache menos eficiente, mais requisições passaram a ser encaminhadas para o S3.
  • Como o CloudFront cobra por requisições e pela transferência de dados entre regiões, isso resultou em um custo muito maior.
  1. Mais tráfego de transferência de dados
  • Com a fragmentação do cache, o CloudFront precisou baixar e armazenar várias cópias de arquivos que antes eram servidos diretamente da CDN, aumentando o consumo de tráfego e elevando os custos.

Resumo do problema

Problema da perda de query strings resolvido.Custo do CloudFront aumentou devido à ativação do “Forward Query Strings”.O cache foi fragmentado, aumentando as requisições para a origem.

Agora veremos como otimizamos essa solução para reduzir custos sem perder as query strings. 🚀

A solução final e a otimização de custos

Anteriormente, vimos como a ativação da opção “Forward Query Strings” resolveu o problema da perda de query strings, mas ao custo de uma fragmentação severa do cache, resultando em um aumento expressivo nos custos do CloudFront. Agora, vamos explorar a solução final que permitiu manter as query strings sem comprometer a eficiência do cache e reduzir os custos.

Otimizando a solução

Com base na análise do problema e no entendimento do efeito e impacto de cada ponto da implementação, fizemos duas mudanças estratégicas:

1- Mudamos a CloudFront Function da Viewer Request para uma Lambda@Edge na Origin Request

Nossa primeira implementação utilizava uma CloudFront Function para ajustar as URLs sem / no final para adicionar a /. O problema é que CloudFront Functions rodam na Viewer Request, ou seja, elas são executadas antes de verificar o cache, o que significa que essa funtion era acionada para cada nova requisição que o CloudFront recebia.

Como descobrimos que quem tem a limitação para lidar com query strings é o S3 e não o CloudFront, entendemos que poderíamos ajustar a funtion para ser executada somente no momento que o conteúdo requisitado não estiver sendo cacheado e precisar ser buscado na origem(S3).

Para conseguirmos este resultado, migramos essa lógica para um Lambda@Edge, e a associamos à Origin Request.

'use strict';

exports.handler = async (event) => {
    const request = event.Records[0].cf.request;
    let uri = request.uri;

    // Se a URI não contém extensão e não termina com '/', adicionamos '/'
    if (!uri.includes('.') && !uri.endsWith('/')) {
        request.uri += '/';
    }

    return request;
};

Fizemos essa mudança, pois as CloudFront Functions não pode ser associadas nas camadas de origin request e origin response, sendo possível atuar nessas camadas somente através da lambda@edge. Isso significa que: ✅ A execução da lambda passou a ser feita somente quando a origem (S3) fosse chamada, usando o cache do CloudFront como uma camada para certificar que a function fosse executada somente quando fosse de fato necessário. ✅ URLs sem / passaram a ser corrigidas antes de serem processadas pelo S3.

Com essa mudança, diminuímos a quantidade de execuções da function e melhoramos a eficiência do cache do CloudFront.

2- Desativamos “Forward Query Strings”

Após testes, percebemos que a perda de query strings não estava relacionada à opção “Forward Query Strings”, mas sim à falta da / no final das URLs.

✅ Com a function forçando a / na Origin Request, garantimos que o CloudFront não precisava fragmentar o cache baseado em query strings. ✅ Desativamos a opção "Forward Query Strings", permitindo que o cache do CloudFront armazenasse apenas uma versão de cada página, independentemente dos parâmetros na URL.

O Impacto das mudanças

Após aplicar essas otimizações, conseguimos: ✔ Manter a preservação das query strings.Melhorar o cache hit ratio do CloudFront.Reduzir drasticamente o número de requisições para a origem (S3).Reduzir drasticamente volume de execuções das Functions associadas ao CloudFront. Diminuir significativamente o custo do CloudFront.

Conclusão

Inicialmente, habilitamos “Forward Query Strings” achando que isso evitaria a perda de query strings, contudo após entender o que a configuração de fato causava, passou a fazer sentido o aumento dos custos devido à fragmentação do cache.

A solução real foi corrigir o problema na URL antes da origem ser chamada, permitindo que o CloudFront funcionasse de forma eficiente, sem precisar armazenar versões duplicadas de páginas devido a query strings diferentes.

Observações importantes

📌 CloudFront Functions são mais baratas que lambda@edge e são mais eficientes para pequenas manipulações na Viewer Request, porém por serem executadas a cada nova request que der match com o behaviour ao qual está associada, seu custo escala de acordo com o volume de acessos que o CloudFront recebe. Esse é um ponto importante a ser avaliado em cenários de sites que recebem tráfego elevado. 📌 Lambda@Edge são mais caras que as CloudFront Functions, porém seu uso pode ser mais adequado quando a lógica pode rodar apenas para requisições que chegam à origem. Dessa forma mesmo sendo mais caras, podem podem gerar menor custo uma vez que forem executada num volume menor. O que buscamos garantir através da camada de cache do CloudFront. 📌 Forward Query Strings deve ser usado apenas quando realmente necessário, pois pode fragmentar o cache e aumentar custos. 📌 Entender o comportamento do S3 e do CloudFront é essencial para identificar em qual componente da infra de fato causava o problema da perda de query strings.

Com essas otimizações, conseguimos preservar as query strings, manter um cache eficiente e reduzir custos significativamente.

Se você já enfrentou problemas parecidos ao utilizar CloudFront + S3, fique a vontade para compartilhar sua experiência nos comentários! 🚀


메타데이터
post_id
b97232d25554
slug
perda-de-query-strings-no-aws-cloudfront-s3-veja-o-por-que-acontece-e-como-resolver-b97232d25554
url
https://medium.com/@everton17/perda-de-query-strings-no-aws-cloudfront-s3-veja-o-por-que-acontece-e-como-resolver-b97232d25554
canonical_url
https://medium.com/@everton17/perda-de-query-strings-no-aws-cloudfront-s3-veja-o-por-que-acontece-e-como-resolver-b97232d25554
author_url
https://medium.com/@everton17
status
ok
fetched_at
2026-07-10 00:10:16