\n\n\n\n Minhas faturas Cloud estão muito altas: O que estou percebendo agora - AgntMax \n

Minhas faturas Cloud estão muito altas: O que estou percebendo agora

📖 13 min read2,570 wordsUpdated Apr 1, 2026

Olá a todos, Jules Martin aqui, de volta ao agntmax.com!

Hoje, quero abordar algo que tem me preocupado, e provavelmente muitos de vocês também, há cerca de um ano: o crescente custo da infraestrutura em nuvem, especialmente no que diz respeito às funções sem servidor. Todos nós fomos seduzidos pelo sonho do “pagar apenas pelo que você usa”, e por muito tempo, isso parecia ser uma realidade. Mas ultimamente, vi as contas subirem, às vezes de forma inexplicável, mesmo quando os padrões de tráfego pareciam estáveis. É como se estivéssemos sendo consumidos pela mesma flexibilidade que adotamos. Então, vamos explorar algo muito específico e atual: Dominando o Monstro Sem Servidor: Revelando e Reduzindo os Custos Ocultos do AWS Lambda.

Minha própria jornada nesse campo começou há cerca de seis meses. Temos um microserviço central que gerencia a autenticação de usuários e a gestão de sessões. Ele é quase totalmente construído sobre AWS Lambda, API Gateway, DynamoDB e Cognito. Por muito tempo, os custos foram perfeitamente previsíveis. Então, no verão passado, nossa conta da AWS para esse serviço específico disparou cerca de 15%. Sem novas funcionalidades, sem picos significativos de tráfego. A princípio, atribuí isso a uma flutuação sazonal ou a um pequeno bug que ainda não tinha encontrado. Mas quando a conta do mês seguinte chegou ainda mais alta, percebi que precisava investigar mais. Não era apenas um pico; era uma tendência, e isso estava nos custando dinheiro real.

A Ilusão dos Níveis “Gratuitos” e a Realidade das Invocações “Minúsculas”

Um dos maiores atrativos do sem servidor, especialmente para startups ou pequenas equipes, é o generoso nível gratuito. E ele é generoso! Um milhão de invocações gratuitas por mês para Lambda, além de uma quantidade significativa de tempo de computação. O problema é que, à medida que sua aplicação cresce, essas invocações “gratuitas” desaparecem mais rápido do que uma fatia de pizza em um meetup de tecnologia. O que muitas vezes é negligenciado são os volumes totais de invocações minúsculas, aparentemente insignificantes, que se acumulam. Pense nas tarefas cron, nas verificações de saúde internas ou mesmo nos mecanismos de reenvio provenientes de outros serviços. Cada uma dessas invocações conta.

Minha investigação sobre nosso serviço de autenticação revelou exatamente isso. Tínhamos uma função Lambda, vamos chamá-la de auth-token-refresher, projetada para atualizar periodicamente os tokens de serviço internos. Ela estava programada para ser executada a cada cinco minutos. Parece inofensivo, não é? 288 invocações por dia. Multiplique isso por 30 dias e você tem 8.640 invocações por mês. Adicione nossos ambientes de desenvolvimento, staging e produção, e de repente isso representa mais de 25.000 invocações apenas para uma pequena tarefa de manutenção. Tínhamos uma dúzia de funções como essa. De repente, nossas invocações “minúsculas” não eram mais tão pequenas assim.

Encontrando os Culpados: As Métricas CloudWatch São Seu Melhor Amigo

A primeira etapa para dominar essa fera é saber para onde está indo seu dinheiro. AWS CloudWatch é imprescindível aqui. Não se contente em olhar o painel de faturamento de alto nível; explore as métricas específicas de suas funções Lambda.

Aqui está no que me concentrei:

  1. Invocações: Esta é a métrica mais simples. Contagens elevadas de invocações para funções que não gerenciam tráfego direto de usuários são sinais de alerta imediatos.
  2. Duração: Quanto tempo dura cada invocação? Durações mais longas significam custos de computação mais altos.
  3. Uso de Memória: Você está superprovisionando memória para suas funções? Você paga pelo que aloca, não pelo que usa.
  4. Taxa de Erros: Taxas de erro elevadas podem resultar em reenvios, o que significa mais invocações e ciclos de computação desperdiçados.

Para o nosso auth-token-refresher, eu examinei sua métrica `Invocações`. De fato, ela estava executando como um relógio, a cada cinco minutos. A duração era mínima, apenas cerca de 50 ms. Mas o volume enorme contribuía para nosso custo total de invocação.

Exemplo Prático 1: Consolidar e Programar de Forma Mais Inteligente

A solução para auth-token-refresher e várias outras funções de manutenção semelhantes era surpreendentemente simples: a consolidação. Em vez de ter funções Lambda individuais acionadas por eventos CloudWatch (ou EventBridge nos dias de hoje) em horários separados, criei uma única função Lambda “Maintenance Runner”.

Esse “Maintenance Runner” é acionado por uma única regra de evento CloudWatch, digamos, uma vez por hora. Dentro desse runner, tenho um simples despachador que verifica a hora atual e executa as tarefas necessárias. Por exemplo:


import os
import datetime

def lambda_handler(event, context):
 current_hour = datetime.datetime.now().hour
 current_minute = datetime.datetime.now().minute

 # Tarefa 1: Atualizar o token de autenticação (executava a cada 5 mins)
 if current_minute % 10 == 0: # Agora executa a cada 10 minutos
 print("Executando a atualização do token de autenticação...")
 # Chamar a lógica real de atualização do token ou outra função interna
 refresh_auth_token()

 # Tarefa 2: Limpar os logs antigos (executava a cada hora)
 if current_hour % 1 == 0 and current_minute == 0: # Executa no início da hora
 print("Executando a limpeza dos logs...")
 cleanup_old_logs()

 # Tarefa 3: Verificar o estado dos serviços externos (executava a cada 30 mins)
 if current_minute == 0 or current_minute == 30:
 print("Verificando o estado dos serviços externos...")
 check_external_service()

 return {
 'statusCode': 200,
 'body': 'Tarefas de manutenção executadas.'
 }

def refresh_auth_token():
 # ... lógica real de atualização de token ...
 pass

def cleanup_old_logs():
 # ... lógica real de limpeza de logs ...
 pass

def check_external_service():
 # ... lógica real de verificação de serviços externos ...
 pass

Esta simples mudança reduziu imediatamente o número de invocações para essas tarefas de manutenção de centenas de milhares por mês para alguns milhares. As economias foram tangíveis, não apenas em relação às invocações Lambda, mas também em relação à ingestão dos logs CloudWatch e às chamadas à API Gateway (se algum deles fosse exposto via API Gateway).

O Perigo da Superprovisionamento de Memória

Esse é outro fator de custo sutil que muitas vezes é negligenciado. Quando você cria uma função Lambda, aloca uma certa quantidade de memória (por exemplo, 128 MB, 256 MB, 512 MB). Você paga por essa memória alocada, não importa quanto sua função use realmente. Além disso, a potência da CPU evolui proporcionalmente à alocação de memória. Então, se você alocar 1 GB de memória para um simples script Python que só precisa de 128 MB, você não está apenas pagando demais pela memória; você também está pagando por ciclos de CPU extras dos quais não precisa.

Aprendi isso da maneira mais difícil com uma função Lambda de processamento de dados que estava inicialmente configurada com 1 GB de memória “apenas por precaução”. Quando olhei suas métricas CloudWatch para o uso da memória, ela permanecia sistematicamente abaixo de 200 MB, mesmo em períodos de alta carga. Basicamente, estávamos pagando por 800 MB de RAM não utilizada e o aumento correspondente de CPU.

Exemplo Prático 2: Otimizar a Alocação de Memória com Lambda Power Tuning

Determinar manualmente a configuração de memória ideal pode ser trabalhoso. Você precisa implantar, testar, monitorar, ajustar e repetir. Felizmente, existe uma ótima ferramenta de código aberto chamada AWS Lambda Power Tuning (desenvolvida por Alex Casalboni na AWS) que facilita esse processo.

É um aplicativo sem servidor que ajuda você a visualizar e identificar a configuração de memória ideal para suas funções Lambda com base em custos e desempenho. Você a implanta em sua conta AWS, e então pode usá-la para testar suas funções.

Aqui está geralmente como isso funciona:

  1. Você implanta a ferramenta Power Tuning através do Serverless Application Repository ou SAM.
  2. Você aciona uma máquina de estados (criada pela ferramenta) com o ARN de sua função Lambda e um payload.
  3. A máquina de estados aciona sua Lambda várias vezes com configurações de memória variadas (por exemplo, 128 MB, 256 MB, 512 MB, 1024 MB, etc.).
  4. Ela analisa então os logs de execução e fornece uma visualização mostrando os compromissos de custo e velocidade para cada configuração de memória.

Para minha função Lambda de processamento de dados, ao passá-la pelo Power Tuner, descobri que 256 MB era a melhor escolha em termos de custo, com uma degradação de performance negligenciável em relação a 1 GB. Imediatamente reduzimos a alocação de memória para 256 MB, resultando em uma redução de 75% nos custos de computação para essa função específica. Não foi um caso isolado; desde então, passei a fazer uso desse recurso para novas funções ou aquelas reavaliadas.

Para utilizá-lo, após o deployment, você geralmente iniciaria a máquina de estados com algo assim (ajustando o ARN e o payload):


aws stepfunctions start-execution \
 --state-machine-arn "arn:aws:states:REGIÃO:ID_CONTA:stateMachine:powerTuningStateMachine" \
 --input '{ "lambdaARN": "arn:aws:lambda:REGIÃO:ID_CONTA:function:NOME_DA_SUA_FUNCAO", "num": 100, "payload": {}, "parallel": 5 }'

A saída fornece um gráfico claro, mostrando exatamente onde seus custos e sua velocidade se cruzam para uma performance ideal. É uma mudança significativa para a otimização de custos.

Verboso dos Logs e Inícios a Frio

Outras duas áreas que podem frequentemente surpreendê-lo são a verbosidade dos logs e os inícios a frio. Os logs do CloudWatch não são gratuitos. Cada linha que sua função Lambda imprime é ingerida e armazenada, e você paga por isso. Embora uma boa análise de logs seja crucial para debugging, um registro excessivamente verboso (por exemplo, imprimir objetos inteiros ou repetir mensagens de status desnecessariamente) pode rapidamente aumentar sua fatura do CloudWatch Logs.

Encontrei algumas funções que registravam o corpo inteiro das requisições HTTP a cada invocação. Embora isso seja útil para o desenvolvimento inicial, em produção, apenas gerava ruído e custava dinheiro. Um ajuste rápido para registrar apenas os metadados essenciais (ID de requisição, código de status, endpoint) reduziu significativamente nossa ingestão de logs.

Os inícios a frio, embora não representem um “custo” direto da mesma forma, afetam a experiência do usuário e podem indiretamente resultar em mais re-tentativas ou em períodos de faturamento mais longos se sua função precisar esperar por recursos. Embora a AWS tenha feito avanços significativos para reduzir os tempos de início a frio, otimizar o tamanho do pacote da sua função e evitar uma lógica de inicialização complexa fora do handler ainda pode fazer diferença. Para funções críticas sensíveis à latência, a concorrência provisionada é uma opção, mas tenha em mente que você paga por essa concorrência alocada mesmo quando está ociosa.

Exemplo Prático 3: Logs Inteligentes e Variáveis de Ambiente

Para o log, a solução mais simples é muitas vezes a melhor. Use variáveis de ambiente para controlar os níveis de log. Em Python, por exemplo, você pode fazer assim:


import os
import logging

LOG_LEVEL = os.environ.get('LOG_LEVEL', 'INFO').upper()
logging.basicConfig(level=LOG_LEVEL)
logger = logging.getLogger()

def lambda_handler(event, context):
 logger.debug("Esta é uma mensagem de debug, visível apenas se LOG_LEVEL for DEBUG")
 logger.info("Processando evento: %s", event.get('request_id'))
 try:
 # ... lógica da função ...
 logger.debug("Processamento concluído para request_id: %s", event.get('request_id'))
 return {
 'statusCode': 200,
 'body': 'Sucesso'
 }
 except Exception as e:
 logger.error("Erro ao processar request_id %s: %s", event.get('request_id'), str(e), exc_info=True)
 return {
 'statusCode': 500,
 'body': 'Erro'
 }

Definindo LOG_LEVEL para INFO em produção e DEBUG em desenvolvimento/staging, você pode reduzir consideravelmente sua fatura do CloudWatch Logs sem sacrificar a observabilidade quando precisar.

Outra dica é prestar atenção ao que é inicializado fora do handler. Qualquer código diretamente na scope global da sua função Lambda será executado durante o início a frio. Se você tiver operações custosas como pool de conexão com o banco de dados ou grandes imports de bibliotecas, considere adiá-las até que sejam realmente necessárias no handler, ou certifique-se de que estão sendo eficientemente armazenadas em cache para as próximas invocações quentes.

Pontos Chave para Sua Cruzada Contra Custos sem Servidor

Certo, cobrimos bastante coisa. Aqui está um resumo das etapas práticas que você pode tomar agora mesmo para começar a reduzir essas traiçoeiras despesas Lambda:

  • Monitore sem parar: Não se contente em dar uma olhada na sua fatura AWS geral. Explore as métricas do CloudWatch para Invocações, Duração e Uso da Memória para cada função Lambda. Configure alarmes para picos inesperados.
  • Consolide as tarefas cron: Se você tiver várias pequenas funções Lambda agendadas, considere combiná-las em um único “Maintenance Runner” que distribua tarefas segundo um cronograma menos frequente. Isso reduz consideravelmente o número de invocações.
  • Otimize a alocação de memória: Use ferramentas como AWS Lambda Power Tuning para encontrar a configuração de memória ideal para suas funções. Não faça suposições e não provisionar em excesso. Lembre-se, mais memória significa mais CPU, e você paga por ambas.
  • Acompanhe a verbosidade dos logs: Implemente níveis de log controlados por variáveis de ambiente (por exemplo, INFO para produção, DEBUG para desenvolvimento). Evite registrar corpos completos de requisições ou um estado interno excessivo em produção. Sua fatura do CloudWatch Logs vai agradecer.
  • Revise funções não utilizadas: Audite periodicamente suas funções Lambda. Existem funções antigas, experimentais ou obsoletas ainda ativas e gerando custos? Elimine-as!
  • Monitore o tamanho dos pacotes: Pacotes de deploy menores significam inícios a frio mais rápidos e menores custos de armazenamento. Inclua apenas as dependências necessárias.
  • Entenda seu modelo de faturamento: Leia a página de preços do Lambda. Entenda como as invocações, GB-segundos e a transferência de dados são cobrados. Conhecimento é poder, especialmente quando se trata do seu bolso.

Dominar o monstro sem servidor não é uma questão de evitar o sem servidor; é sobre ser inteligente e intencional na maneira como o usamos. A flexibilidade e escalabilidade são inestimáveis, mas sem a vigilância adequada, esses “pequenos” custos podem se acumular e representar uma parte significativa do seu orçamento. Vá em frente, monitore, otimize e economize!

Então, é isso por hoje. Deixe seu comentário se você tiver mais dicas ou sugestões para otimização de custos Lambda!

🕒 Published:

✍️
Written by Jake Chen

AI technology writer and researcher.

Learn more →
Browse Topics: benchmarks | gpu | inference | optimization | performance

Partner Projects

AgnthqAgntaiBotclawClawseo
Scroll to Top