Apostila completa de Otimização de Custos de Cloud e IA
Esta é a caixa de ferramentas técnica: rightsizing, spot, commitments, tiers de armazenamento, egress, serverless, custo de warehouse e de Kubernetes, e o capítulo que mais cresce — o custo de inferência e treino de IA (tokens, GPU, caching, quantização, self-host vs API). A disciplina, a cultura e o processo estão na apostila irmã de FinOps; aqui a pergunta é sempre "como eu baixo esta linha da fatura sem perder desempenho nem confiabilidade?".
Onde o dinheiro está e como medir antes de cortar
Objetivo: saber quais categorias dominam uma fatura de nuvem, adotar a mentalidade de medir antes de agir, e situar esta apostila em relação à de FinOps.
1.1 A distribuição típica de uma fatura
| Categoria | Fatia comum | Onde este material ataca |
|---|---|---|
| Compute (VMs, contêineres, funções) | 40–70% | Módulos 2–4, 7, 8 |
| Armazenamento (objeto, bloco, backup) | 10–25% | Módulo 5 |
| Transferência de dados (egress, inter-AZ/region) | 5–20% (e cresce escondido) | Módulo 6 |
| Serviços gerenciados (bancos, filas, analytics) | 10–30% | Módulos 7–8 |
| IA / GPU / APIs de LLM | 0 → pode virar a maior linha, rápido | Módulo 9 |
Regra de priorização: vá primeiro à maior categoria e ao maior serviço dentro dela. Uma economia de 20% em compute (que é 60% da fatura) vale mais que 80% numa linha que é 2%.
1.2 Medir antes de cortar
Reduzir uma instância "no chute", desligar um recurso que "parecia ocioso", comprar commitment sobre um uso que vai mudar — todos geram dor. O ciclo correto: medir (métricas de utilização de um período representativo, incluindo pico) → hipótese de economia com estimativa de risco → mudança gradual → observar (a métrica de desempenho piorou?) → repetir. Toda ação desta apostila pressupõe esse ciclo.
- Fonte de verdade: o relatório detalhado de faturamento (AWS CUR, GCP Billing Export, Azure Cost details), idealmente num warehouse ou ferramenta de análise. O padrão aberto FOCUS normaliza esses formatos.
- Métricas de utilização: CPU, memória, rede, IOPS, GPU — do provedor (CloudWatch, Cloud Monitoring) ou do seu observability stack, janela de 2–4 semanas.
- Ligue custo a uma unidade de valor (custo por requisição, por cliente, por job) — a apostila de FinOps detalha; aqui, basta ter o denominador para não confundir "gastou mais porque cresceu" com "gastou mais porque desperdiça".
1.3 As duas grandes alavancas
- Pagar menos pelo mesmo (otimização de taxa): commitments, spot, tiers de storage, ARM, negociação. Não muda o que roda.
- Usar menos (otimização de uso): rightsizing, autoscaling, parking, eliminar desperdício, arquitetura mais eficiente, código mais eficiente.
Ordem: elimine desperdício e faça rightsizing primeiro, depois aplique descontos sobre a base já enxuta — nunca comprometa 1–3 anos de algo superdimensionado.
Vagas de "Cloud Cost Engineer", "Cloud Economist", "Performance & Cost Optimization". Pergunta de abertura: "Por onde você começa uma otimização de custos de nuvem?" — a resposta forte: identificar a maior categoria/serviço na fatura, medir utilização real, atacar desperdício e rightsizing antes de comprar desconto, e sempre medir o impacto no desempenho.
✏️ Exercício 1 — Priorize
Fatura mensal de R$ 120k: compute 55%, storage 18%, transferência 12%, RDS gerenciado 10%, resto 5%. Você tem 2 semanas. Onde foca e por quê?
Gabarito: Compute (R$ 66k) — a maior alavanca. Nas 2 semanas: (1) rightsizing das instâncias com baixa utilização de pico + migrar cargas compatíveis para ARM; (2) parking de ambientes não-produtivos; (3) spot para cargas batch/CI. Só depois olhar RDS (rightsizing da instância, storage autoscaling, réplicas ociosas) e transferência (Módulo 6). Storage rende menos e mais devagar (lifecycle policies levam tempo para "esfriar" os dados). Comprar Savings Plan fica para depois de a base de compute estar enxuta.
Compute I — rightsizing e elasticidade
Objetivo: ajustar o tamanho e o tipo do compute ao que a carga realmente usa, e fazer a capacidade acompanhar a demanda em vez de pagar pelo pico o tempo todo.
2.1 Rightsizing
- Colete métricas de 2–4 semanas (incluir picos e sazonalidade): CPU (média e p95/p99), memória, rede, IOPS.
- Compare com o provisionado: uma VM com CPU de pico < 40% e memória < 50% é candidata a descer um ou dois tamanhos.
- Escolha o tipo certo, não só o tamanho: família compute-optimized, memory-optimized, general, burstable (T-family / e2 — ótimas para cargas com CPU baixa e picos curtos, péssimas para CPU sustentada).
- Gerações mais novas quase sempre têm melhor preço/desempenho — migrar da geração N-2 para a N costuma dar 10–20% de graça.
- Aplique gradual, com margem para pico e crescimento, monitorando latência/erro depois.
Processadores ARM dos provedores (AWS Graviton, Google Axion, Azure Cobalt) entregam tipicamente 20–40% melhor preço/desempenho para cargas compatíveis — a maioria das aplicações em linguagens gerenciadas (Java, Go, Python, Node, .NET) e muitos bancos e runtimes já rodam nativamente. Custo de migração baixo (rebuild multi-arch da imagem), ganho recorrente alto. É das otimizações com melhor relação esforço/retorno hoje.
2.2 Autoscaling
| Mecanismo | O que ajusta | Nota |
|---|---|---|
| Horizontal (HPA / ASG) | Nº de réplicas/instâncias por métrica (CPU, RPS, tamanho de fila) | O principal; exige serviço stateless |
| Vertical (VPA) | Recursos (CPU/mem requests) de cada pod | Ótimo em modo "recomendação" para guiar rightsizing de contêineres |
| Cluster autoscaler / Karpenter | Nº e tipo de nós do cluster K8s | Consolida pods, derruba nós vazios, escolhe instância mais barata que cabe |
| Scale-to-zero | Serviço vai a 0 réplica sem tráfego | Knative, KEDA, Cloud Run, Lambda; cuidado com cold start |
| Scheduled scaling | Capacidade por horário conhecido | Para padrões previsíveis (horário comercial, batch noturno) |
Configure com cuidado: métrica-alvo realista, limites mínimo/máximo, cooldown para não oscilar (flapping), e headroom para o autoscaler ter tempo de reagir ao pico. Autoscaling mal ajustado ou causa incidente (subiu tarde demais) ou não economiza (mínimo alto demais).
Perguntas: "Como você faz rightsizing sem risco?" (métricas de 2–4 semanas com pico, margem, gradual, monitorar), "Quando NÃO usar instância burstable?" (CPU sustentada — os créditos acabam e ela estrangula), "Qual o ganho típico de migrar para ARM e qual o custo?", "Como evitar flapping no autoscaling?" (cooldown, métrica estável, headroom).
✏️ Exercício 2 — Diagnóstico de frota
50 VMs m5.2xlarge (8 vCPU) rodando um serviço web em Java. Métricas de 30 dias: CPU média 18%, pico 46%; memória média 55%. Tráfego tem padrão diário claro (2× mais de dia). Proponha as mudanças e a economia aproximada.
Gabarito: (1) Rightsizing: pico de 46% em 8 vCPU ⇒ cabe em 4 vCPU com folga (m5.xlarge ou m6g.xlarge). Já ~50% de economia por instância. (2) ARM: Java roda bem em Graviton ⇒ m7g.xlarge, mais ~15–20%. (3) Autoscaling horizontal pelo padrão diário: em vez de 50 fixas, ~30 à noite e ~50 no pico ⇒ mais ~20% no compute. (4) Savings Plan cobrindo a base que fica de pé 24/7 (~30 instâncias) depois de estabilizar. Combinado: fácil passar de -50% no custo dessa frota, sem tocar em desempenho (pico projetado ainda < 60%).
Compute II — spot, parking e ambientes efêmeros
Objetivo: usar capacidade descontada e interrompível onde ela cabe, e parar de pagar por ambientes que só trabalham no horário comercial.
3.1 Spot / preemptible a fundo
Capacidade ociosa do provedor, 60–90% mais barata, que pode ser retomada com aviso curto (segundos a 2 minutos). O trade-off é explícito: você desiste de garantia de continuidade em troca de preço.
Cargas que combinam com spot
- Jobs batch e pipelines de dados (ETL, Spark) — reiniciam do checkpoint.
- CI/CD runners, testes, builds.
- Rendering, transcodificação, processamento científico.
- Treino de ML com checkpointing; inferência stateless atrás de fila com réplicas em várias pools.
- Workers de fila idempotentes — a mensagem volta para a fila se o worker morre.
Como usar spot com segurança
- Diversifique entre vários tipos de instância e zonas (spot fleet / mixed instances policy / Karpenter) — a chance de todas serem retomadas ao mesmo tempo cai muito.
- Trate o sinal de interrupção: drenar conexões, salvar checkpoint, devolver a tarefa à fila.
- Fallback para on-demand quando não houver capacidade spot (a política do autoscaler faz isso).
- Nunca spot para: bancos de dados stateful primários, nós de controle, cargas que não toleram reinício.
3.2 Parking: parar o não-produtivo
Ambientes de desenvolvimento, staging, QA e demo raramente precisam rodar 24/7. Uma carga que roda 12h em dias úteis (~60 h/semana em vez de 168) custa ~35% do valor; 8h/dia útil, ~25%.
- Agendador de start/stop (Instance Scheduler, cron + API, ferramenta de FinOps,
kube-downscalerpara K8s). - "Ligar sob demanda": botão/Slack command para o dev subir o ambiente quando precisar fora de hora.
- Bancos gerenciados de dev também param (RDS/Cloud SQL têm stop; ou snapshot + destroy + restore).
- Exceções conscientes (um ambiente de testes noturnos automatizados) documentadas.
3.3 Ambientes efêmeros
Em vez de ambientes de staging permanentes, crie um ambiente por pull request (preview environment), destruído no merge/close. Zero recurso esquecido ligado, e cada mudança testada em isolamento. Ferramentas: preview deployments (Vercel/Netlify para front), terraform workspace + pipeline, namespaces efêmeros em K8s, Crossplane/vCluster.
Perguntas: "Que cargas você colocaria em spot e como as protege?" (batch/CI/workers idempotentes; diversificar pools, tratar interrupção, fallback on-demand), "Quanto custa parkear um ambiente de dev?" (~25–35% do valor 24/7), "O que são ambientes efêmeros e por que ajudam no custo?" (nada fica esquecido ligado).
✏️ Exercício 3 — Onde entra spot
Uma empresa tem: (a) cluster de API de produção; (b) pipeline de dados noturno de 3h em Spark; (c) 40 runners de CI; (d) banco Postgres primário; (e) workers que consomem uma fila SQS e são idempotentes. Classifique cada um: on-demand, spot, ou spot com cuidados.
Gabarito: (a) On-demand (com Savings Plan na base) — produção síncrona não tolera retomada em massa; pode ter uma fração em spot com fallback se o autoscaler for bom. (b) Spot — Spark reinicia do checkpoint, 3h de janela, economia de 60–90%. (c) Spot — runners são descartáveis; job reencaminhado se o runner morre. (d) On-demand sempre — primário stateful. (e) Spot — idempotente + fila devolve a mensagem; diversificar pools.
Descontos por compromisso: Savings Plans, RIs e CUDs
Objetivo: reduzir o preço unitário do compute estável comprometendo uso ou gasto, gerindo cobertura e utilização como um portfólio.
4.1 O vocabulário e os instrumentos
| Instrumento | Compromisso | Flexibilidade | Desconto típico |
|---|---|---|---|
| Reserved Instance (RI) | Família/tipo de instância específico, 1 ou 3 anos | Baixa (mas há "convertible") | até ~60–72% (3 anos, all upfront) |
| Compute Savings Plan (AWS) | Valor de gasto/hora em compute, 1 ou 3 anos — vale para EC2, Fargate, Lambda, qualquer região/família | Alta | ~até 66% |
| EC2 Instance Savings Plan | Gasto/hora numa família + região | Média | um pouco maior que o Compute SP |
| Committed Use Discount (GCP) | vCPU/RAM (resource-based) ou gasto (flexible), 1 ou 3 anos | Média a alta | ~28–46%+ |
| Azure Reservations / Savings Plans | Equivalentes | Média a alta | ~até 65% |
4.2 As duas métricas que você gerencia
- Cobertura (coverage): % do uso elegível protegido por commitment. Meta: cobrir ~70–85% da base estável — não 100%, para ter folga de encolher sem ficar com commitment ocioso.
- Utilização (utilization): % do commitment comprado que está sendo usado. Meta: > 95%. Utilização baixa = comprou demais = pior que on-demand.
4.3 Estratégia prática
- Faça a faxina primeiro (Módulos 2–3): commitment sobre desperdício é dinheiro queimado por 1–3 anos.
- Cubra a base sólida: o que você tem quase certeza que estará rodando daqui a 1–3 anos.
- Prefira o instrumento flexível (Compute Savings Plan / CUD flexible) salvo se a carga for imóvel e o desconto extra do RI rígido for grande.
- Escalone (laddering): compre em ondas ao longo do ano, com vencimentos distribuídos, acompanhando o crescimento — evita "renovar tudo" num mês só.
- Comece com 1 ano se há incerteza; migre para 3 anos a parte que provou ser estável.
- Automação: ferramentas como ProsperOps, Spot.io, ou os próprios "recommendations" do provedor ajustam o portfólio continuamente; some marketplace de RIs para revender excedente (na AWS).
- Revisão semanal de cobertura e utilização, com dono.
Perguntas: "Diferença entre RI e Savings Plan" (SP compromete gasto/hora e é flexível; RI compromete instância e desconta mais mas prende), "Deve mirar 100% de cobertura?" (não — folga para reduzir), "Utilização de 80% do commitment: bom ou ruim?" (ruim — 20% pago e não usado, pior que on-demand), "Rightsizing ou commitment primeiro?" (rightsizing).
✏️ Exercício 4 — Monte a cobertura
Base de compute estável de US$ 20/h há 12 meses, crescendo ~3%/mês. Nenhum commitment. A empresa tem caixa e tolera 3 anos. Proponha.
Gabarito: Cobrir ~70% da base atual (US$ 14/h) com Compute Savings Plan; dentro disso, ~US$ 10/h em 3 anos (a parte mais consolidada) e ~US$ 4/h em 1 ano (margem de manobra). Deixar ~30% (US$ 6/h) em on-demand como folga para redução e para o crescimento absorver. Reavaliar a cada trimestre: conforme a base cresce e se confirma, comprar novas camadas de SP escalonadas. Nunca passar de ~85% de cobertura para não arriscar utilização < 95%.
Storage — tiers, ciclo de vida e limpeza
Objetivo: pagar pelo armazenamento na classe certa, mover o dado frio automaticamente, e eliminar o lixo que se acumula silenciosamente.
5.1 Object storage: classes e ciclo de vida
| Classe (exemplo AWS S3) | Para quê | Custo relativo de armazenamento |
|---|---|---|
| Standard | Dados quentes, acesso frequente | 1× |
| Standard-IA / One Zone-IA | Acesso infrequente, retrieval rápido | ~0,55× (+ taxa por acesso) |
| Glacier Instant / Flexible | Arquivo com retrieval em minutos/horas | ~0,2× / ~0,1× |
| Glacier Deep Archive | Retenção legal, acesso raríssimo (horas) | ~0,04× |
| Intelligent-Tiering | Move automaticamente entre tiers pelo padrão de acesso | Standard + pequena taxa de monitoramento |
- Lifecycle policies: "após 30 dias → IA; após 90 → Glacier; após 365 → Deep Archive ou expira". Configura uma vez, economiza para sempre.
- Intelligent-Tiering quando o padrão de acesso é imprevisível — evita a taxa de retrieval de mover cedo demais para IA.
- Cuidado com objetos pequenos: classes IA/Glacier têm tamanho mínimo cobrado (128 KB) e taxa por objeto — mover milhões de arquivos minúsculos para Glacier pode aumentar o custo.
5.2 A faxina de storage
- Discos (block) órfãos: volumes EBS/PD sem instância anexada — puro desperdício. Inventário + alarme + expiração.
- Snapshots antigos: política de retenção (manter N diários, M semanais, ...); apagar o resto. Snapshots incrementais escondem custo em cadeia.
- Versões e deletes marcados: buckets com versioning acumulam versões antigas para sempre sem lifecycle rule.
- Uploads multipart incompletos: regra para abortar após X dias.
- Backups além do necessário: alinhar retenção ao requisito real (RPO/legal), mover backups antigos para archive.
- Logs: retenção por criticidade, exportar para storage barato, comprimir.
5.3 Block storage: o tipo certo
- gp3 > gp2 (AWS): gp3 é mais barato por GB e permite provisionar IOPS/throughput separadamente do tamanho — não precisa mais "inflar o disco" para ganhar IOPS. Migrar gp2→gp3 é ganho fácil.
- io2/Provisioned IOPS só onde a latência exige; muita gente provisiona IOPS "por segurança" e nunca usa.
- Redimensionar discos superdimensionados (alguns provedores só permitem crescer — planejar).
5.4 Formato e compressão de dados
Onde você controla o formato (data lake, exports, logs): Parquet + compressão (zstd, snappy) reduz o volume armazenado em 5–10× vs CSV/JSON e ainda barateia as consultas (Módulo 8 e apostila de Engenharia de Dados). Comprimir logs e artefatos antes de arquivar.
Perguntas: "Como você reduz custo de object storage?" (lifecycle policies + intelligent-tiering + limpeza de versões/uploads incompletos), "Quando Intelligent-Tiering vs lifecycle manual?" (padrão imprevisível → IT; previsível → regra manual), "gp2 ou gp3?" (gp3, IOPS desacoplado do tamanho), "Armadilha de mover arquivos pequenos para Glacier?" (mínimo de 128 KB + taxa por objeto).
✏️ Exercício 5 — Plano de storage
Bucket com 200 TB: 5 TB acessados na última semana, 40 TB no último mês, o resto (155 TB) são logs e exports com > 6 meses, acessados raríssimas vezes para auditoria. Versioning ligado, sem lifecycle. Proponha.
Gabarito: (1) Lifecycle: objetos com > 90 dias → Glacier Flexible; > 365 dias → Deep Archive; versões não-atuais → expira após 30–90 dias; abortar multipart incompleto após 7 dias. Isso leva os 155 TB de ~1× para ~0,04–0,1×. (2) Os 40 TB do último mês → Standard-IA (ou deixar Intelligent-Tiering cuidar). (3) 5 TB quentes ficam em Standard. (4) Comprimir os logs/exports (zstd) antes/na escrita — pode cortar o volume pela metade ou mais antes mesmo do tiering. Economia de storage tipicamente > 70% nesse cenário.
Rede e transferência de dados
Objetivo: entender a anatomia do custo de transferência — a linha da fatura que mais surpreende — e os padrões de arquitetura que a reduzem.
6.1 O mapa do egress
| Tipo de tráfego | Custo típico |
|---|---|
| Entrada (ingress) para a nuvem | Quase sempre grátis |
| Saída para a internet (egress) | Caro — a linha que assusta; cai por volume e via CDN/committed |
| Entre regiões | Caro |
| Entre zonas de disponibilidade (mesma região) | Barato por GB, mas enorme em volume em apps chatty — soma muito |
| Dentro da mesma zona / via endpoint privado | Grátis ou muito barato |
| Através de NAT Gateway | Taxa por hora + por GB processado — vilão comum e silencioso |
6.2 Padrões que reduzem transferência
- CDN na frente de tudo que é servido a usuários (CloudFront, Cloud CDN, Cloudflare): egress via CDN é mais barato que direto do storage/compute, e o cache reduz o volume de origem. Assets, imagens, vídeo, respostas de API cacheáveis.
- Colocalize o que conversa muito: serviço e banco na mesma zona; evitar chamadas cross-AZ no caminho quente. Em K8s, topology aware routing mantém o tráfego na zona.
- VPC endpoints / Private Service Connect / Private Link para acessar S3, DynamoDB, APIs do provedor sem passar pela internet nem pelo NAT Gateway — corta a taxa do NAT e o egress.
- Revise o NAT Gateway: tráfego grande de saída (baixar imagens de contêiner, pacotes, backups para outra nuvem) passando pelo NAT paga por GB. Mover para endpoint privado, cache de imagens (pull-through cache do ECR/Artifact Registry), ou gateway próprio.
- Comprima respostas HTTP (gzip/brotli) e payloads entre serviços.
- Data locality: processe o dado onde ele está (não traga 1 TB para a aplicação para filtrar 1 GB — empurre o filtro para o storage/warehouse).
- Evite multi-region desnecessário: replicação entre regiões é egress contínuo; só onde a latência/DR exigem.
- Egress para fora da nuvem (para outro provedor, on-prem): considerar Direct Connect/Interconnect se o volume for alto e constante.
Alta disponibilidade pede espalhar réplicas por zonas — mas um serviço que faz dezenas de chamadas cross-AZ por requisição, ou um cluster de banco replicando muito entre zonas, gera um egress inter-AZ que não aparece como "uma linha grande", e sim diluído. Meça o tráfego inter-AZ; use roteamento consciente de topologia para manter a conversa dentro da zona quando a resiliência permitir.
Perguntas: "Por que a conta de transferência de dados surpreende e como reduzir?" (CDN, colocalização, endpoints privados, revisar NAT Gateway, comprimir), "O que é o custo do NAT Gateway e como evitá-lo?" (taxa por GB — usar VPC endpoints e pull-through cache), "Como o tráfego inter-AZ vira um problema de custo?" (apps chatty; topology-aware routing).
✏️ Exercício 6 — Rastreie o egress
A fatura mostra R$ 22k/mês em "data transfer". Investigando: R$ 9k é NAT Gateway (GB processado), R$ 7k é egress de imagens servidas direto de um bucket para usuários, R$ 4k é inter-AZ de um cluster de cache, R$ 2k é replicação para outra região. Proponha ações.
Gabarito: (1) NAT R$ 9k: identificar o que sai — provável pull de imagens de contêiner e pacotes; adicionar VPC endpoints para S3/ECR e pull-through cache ⇒ pode zerar boa parte. (2) Imagens R$ 7k: colocar CloudFront/CDN na frente do bucket ⇒ egress mais barato + cache reduz origem; possível queda de 50–80%. (3) Inter-AZ do cache R$ 4k: avaliar réplica de leitura por zona / client-side consistent hashing para atender da mesma AZ; ou aceitar se a HA exige. (4) Replicação inter-region R$ 2k: confirmar se o DR realmente precisa dessa região e dessa frequência; talvez reduzir escopo/cadência.
Serverless e serviços gerenciados
Objetivo: extrair o melhor custo de funções (FaaS) e reconhecer quando um serviço gerenciado deixa de compensar e vale internalizar.
7.1 Otimizar funções (Lambda / Cloud Functions / Azure Functions)
- Tuning de memória: em Lambda, a CPU é proporcional à memória. Mais memória pode reduzir o custo se a função ficar rápida o suficiente (menos GB-segundo). Use uma ferramenta de "power tuning" para achar o ponto ótimo por função — não chute.
- Arquitetura ARM (Graviton) para funções: ~20% mais barato, quase sempre sem mudança de código.
- Reduza o tempo de execução: conexões reaproveitadas fora do handler, dependências enxutas (cold start menor), evitar I/O desnecessário.
- Provisioned concurrency só onde o cold start dói de verdade — ela é "sempre ligada" e custa como tal.
- Cuidado com o padrão de invocação: função chamada em loop por outra função, ou por um trigger muito granular, multiplica invocações. Batching de eventos reduz.
7.2 Serverless × sempre-ligado: o ponto de virada
Serverless brilha em carga intermitente ou imprevisível (escala a zero, paga por uso). Em carga alta e constante, um contêiner/VM reservado costuma custar bem menos por unidade de trabalho. A conta: estime o custo serverless no volume esperado e compare com N contêineres reservados que dariam o mesmo throughput. Muitos sistemas começam serverless (certo) e deveriam migrar a parte de tráfego constante para contêiner quando amadurecem (e vice-versa para picos).
7.3 Serviços gerenciados: quando compensam e quando não
| Compensa o gerenciado quando… | Vale reconsiderar quando… |
|---|---|
| Time pequeno; o custo de operar você mesmo (pessoas, on-call) supera o prêmio | A escala ficou grande e o prêmio do gerenciado virou uma linha enorme |
| Carga variável — o gerenciado escala e você não paga ocioso | Carga estável e previsível, onde uma instância reservada bem operada sai muito mais barata |
| Recurso não é diferencial competitivo | O serviço tem SKUs premium que você está pagando sem usar os recursos |
- Bancos gerenciados: rightsizing da instância, storage autoscaling em vez de superprovisionar, matar réplicas de leitura ociosas, usar tier serverless (Aurora Serverless v2, etc.) para cargas intermitentes, reservar a base.
- Filas/streaming gerenciado: revisar retenção, shards/partições provisionados, e se o volume justifica um tier provisionado vs on-demand.
- Observability SaaS: frequentemente uma das maiores "linhas surpresa" — controlar cardinalidade de métricas, amostragem de traces, retenção de logs, e volume ingerido.
Perguntas: "Como você otimiza custo de Lambda?" (tuning de memória, ARM, reduzir duração, cuidado com provisioned concurrency e padrão de invocação), "Quando serverless fica mais caro que contêiner?" (carga alta e constante), "Quando reconsiderar um serviço gerenciado?" (escala grande + carga estável + prêmio virou linha grande).
✏️ Exercício 7 — Serverless ou não?
Um endpoint de processamento de imagem roda em Lambda: 20 milhões de invocações/mês, 512 MB, ~800 ms cada, tráfego constante o dia todo. O time acha que "serverless é sempre mais barato". Como você avalia?
Gabarito: Tráfego constante e volume alto é exatamente o cenário onde serverless pode perder. Passos: (1) calcular o custo atual em GB-segundo + invocações. (2) Estimar o throughput necessário (20M/mês ≈ ~8/s médio, pico talvez 30–50/s) e quantos contêineres reservados (ex.: Fargate/ECS com Savings Plan, ou EC2) entregariam isso — provavelmente poucas instâncias pequenas. (3) Comparar. (4) Considerar meio-termo: contêineres reservados para a base constante + Lambda só para o pico. Antes de migrar, otimizar o próprio Lambda (ARM, tuning de memória — 512 MB pode não ser o ótimo) para ter a comparação justa.
Custo de dados e de Kubernetes
Objetivo: as duas áreas onde o custo se esconde em detalhes de configuração — o warehouse/pipeline de dados e o cluster de contêineres compartilhado.
8.1 Data warehouse e analytics
| Modelo de cobrança | Alavancas de custo |
|---|---|
| Por dado escaneado (BigQuery on-demand, Athena) | Particionar e clusterizar para escanear menos; nunca SELECT *; materializar consultas repetidas; usar LIMIT não ajuda (escaneia igual); tabelas em Parquet comprimido; incremental em vez de full-scan; custom quotas por usuário/projeto |
| Por tempo de warehouse ligado (Snowflake, BigQuery editions, Redshift) | Auto-suspend agressivo (60 s ocioso); dimensionar o warehouse para a carga (não "XL por segurança"); separar warehouses por workload (ETL vs BI) para dimensionar cada um; multi-cluster só sob concorrência real |
- Monitore as consultas mais caras (top 10 por bytes/tempo) e otimize ou eduque quem as roda.
- Alarme de custo por query e por dia — um
JOINcartesiano ou um dashboard que atualiza a cada 10 s pode gerar milhares num fim de semana. - Storage do warehouse/lake: compactar arquivos pequenos, expirar snapshots de Iceberg/Delta, particionar por data, tiering.
- Pipelines (Spark/ETL): spot para batch, rightsizing do cluster, evitar reprocessamento e shuffle desnecessário (ver apostila de Engenharia de Dados).
8.2 Kubernetes: alocar e enxugar
- Visibilidade primeiro: OpenCost (CNCF) ou Kubecost alocam o custo dos nós por namespace/deployment/label, mostrando requested vs used.
- O grande desperdício é
requestsinflado: pods pedindo muito mais CPU/memória do que usam ⇒ o scheduler "enche" nós de reservas ociosas e o cluster autoscaler cria nós à toa. Ajustar requests para perto do uso real + margem (VPA em modo recomendação ajuda). - Bin packing e consolidação: Karpenter / Cluster Autoscaler para empacotar pods em menos nós, escolher o tipo de nó mais barato que cabe, e derrubar nós subutilizados.
- Spot para workloads tolerantes (batch, stateless com PDB, dev) com node pools separados e fallback.
- Scale-to-zero de serviços sem tráfego (KEDA, Knative).
- Limpar namespaces abandonados, PVCs órfãos, LoadBalancers sem uso, jobs completos acumulados.
- Right-size do control plane e de add-ons (ingress controllers, mesh, agentes de observabilidade — os DaemonSets custam × nº de nós).
Perguntas: "Como reduzir o custo de um warehouse cobrado por dado escaneado?" (particionar/clusterizar, evitar SELECT *, materializar, Parquet), "Por que auto-suspend importa no Snowflake?", "Por que 'requests' mal dimensionados encarecem Kubernetes?" (reservas ociosas forçam mais nós), "O que OpenCost/Kubecost fazem?" (alocação por namespace + gap request-vs-uso).
✏️ Exercício 8 — Warehouse caro
Um BigQuery on-demand custa R$ 30k/mês. Investigação: 60% do custo vem de 4 dashboards que rodam SELECT * sobre uma tabela de eventos de 8 TB não particionada, atualizando a cada 15 min; 25% de um pipeline diário que reprocessa 90 dias toda vez. Proponha.
Gabarito: (1) Particionar a tabela de eventos por data e clusterizar pelas colunas de filtro dos dashboards ⇒ cada refresh passa a escanear MBs/GBs em vez de 8 TB. (2) Trocar SELECT * por só as colunas usadas. (3) Materializar o resultado dos dashboards numa tabela agregada atualizada a cada 15 min (ou usar materialized views / BI engine) ⇒ o dashboard lê KBs. (4) O pipeline: incremental — processar só o dia novo (ou os dias que mudaram), não 90 dias fixos. (5) Custom quota por usuário e alarme de bytes por query. Economia esperada: > 70%.
Otimização de custos de IA e GenAI
Objetivo: controlar o custo de inferência e treino de modelos — tokens, escolha de modelo, caching, batching, GPU, quantização, e a decisão self-host vs API.
9.1 O custo de inferência de LLM via API
Você paga por token, com preço diferente para entrada e saída (a saída costuma ser 3–5× mais cara). As alavancas, da mais barata de aplicar à mais estrutural:
| Tática | Efeito |
|---|---|
| Enxugar o prompt e o contexto | Menos tokens de entrada por chamada; cortar instruções redundantes, exemplos few-shot desnecessários, e histórico antigo da conversa (resumir em vez de reenviar tudo) |
Limitar max_tokens de saída | Teto explícito na resposta; pedir formato conciso; saída estruturada em vez de prosa |
| Prompt caching | Provedores cacheiam o prefixo repetido do prompt (system prompt, instruções, documentos fixos) e cobram muito menos por ele nas chamadas seguintes — estruture o prompt com a parte estável primeiro |
| Cache de respostas / cache semântico | Pergunta idêntica (ou semanticamente equivalente, via embedding) já respondida ⇒ serve do cache, custo zero de LLM |
| Model routing / cascata | Um classificador barato (ou um modelo pequeno) decide a dificuldade; o fácil vai para um modelo pequeno/barato, só o difícil escala para o modelo grande. Cascata: tenta o pequeno, escala se a confiança for baixa |
| Batch API | Para trabalho não urgente (classificação em massa, enriquecimento, avaliação), a API em lote custa ~50% e processa em janela de horas |
| Escolher o modelo certo por tarefa | A maioria das tarefas de extração/classificação/resumo não precisa do modelo top de linha; medir qualidade (ver apostila de LLMOps) e usar o menor que atende |
9.2 GPU: o recurso mais caro
- Utilização de GPU como KPI: GPU a 20% de uso é dinheiro queimado. Medir (DCGM, nvidia-smi exporter) e agir.
- Compartilhamento: MIG (particionar uma GPU em instâncias isoladas) e time-slicing para cargas que não saturam uma GPU inteira.
- Right-size da GPU: nem toda inferência precisa de H100 — modelos menores rodam bem em GPUs mais baratas (L4, A10) ou até CPU.
- Servidores de inferência (vLLM, TGI, TensorRT-LLM, Triton) com continuous batching e paged attention aumentam muito o throughput por GPU ⇒ menos GPUs para o mesmo QPS.
- Autoscaling e scale-to-zero de endpoints de inferência (KServe, escalonar por fila/QPS); aceitar cold start onde o SLA permite.
- Spot para treino com checkpointing frequente; spot para inferência batch.
- Quantização (INT8, FP8, GPTQ/AWQ) e distilação: modelo menor/mais rápido, custo por token menor, com perda de qualidade que você mede e aceita ou não.
9.3 Treino e fine-tuning
- PEFT / LoRA / QLoRA em vez de full fine-tuning: fração da memória e do tempo, roda em GPU menor.
- Spot + checkpointing: retomar de onde parou reduz o custo de treino em 60–90%.
- Mixed precision (bf16/fp16), gradient accumulation e gradient checkpointing para caber em GPU menor / batch maior.
- Não re-treinar à toa: só quando o eval justifica (ver apostilas de MLOps e LLMOps).
- Dados: curar um dataset menor e melhor costuma bater um dataset gigante — menos GPU-hora.
9.4 Self-host × API: o break-even
API gerenciada: zero infra, paga por token, ótimo para volume baixo/variável e para começar. Self-host (modelo aberto em GPU sua): custo fixo alto (GPUs reservadas + operação), barato por token em volume alto e constante.
Regra de bolso para estimar o break-even:
custo_mensal_API ≈ tokens/mês × preço_por_token
custo_mensal_self ≈ (nº_GPUs × preço_GPU_hora × 730) + operação
self-host começa a compensar quando os tokens/mês são altos o bastante
para manter as GPUs bem utilizadas (continuous batching) o tempo todo.
Volume baixo ou muito variável → API. Volume alto, constante e previsível → self-host.
Considere também: latência, privacidade/compliance, e o custo de engenharia.
9.5 Observabilidade e guardrails de custo de IA
- Custo por requisição registrado no gateway de LLM (tokens in/out × preço, por modelo, por feature, por usuário) — sem isso você não sabe onde cortar.
- Unit economics: custo por resposta / por documento / por usuário de IA, e se cabe no preço do produto.
- Orçamento por requisição e por tenant, com corte ao estourar; rate limit e quota por usuário (protege contra denial of wallet — ver apostila de Segurança de Aplicações de IA).
- Alarme de anomalia de custo de IA — um loop de agente ou um prompt que cresceu pode multiplicar a conta rápido.
Área que mais cresce em vagas de "AI infra" / "LLM cost". Perguntas: "Como reduzir o custo de um produto com LLM sem perder qualidade?" (enxugar contexto, cap de saída, prompt caching, cache semântico, model routing, batch API, modelo menor validado por eval), "O que é continuous batching e por que barateia inferência?", "Quando self-host compensa vs API?" (volume alto e constante que mantém a GPU utilizada), "LoRA vs full fine-tuning em termos de custo".
✏️ Exercício 9 — Corte a conta de IA
Um assistente de suporte via API de LLM custa R$ 80k/mês: 2M requisições, prompt médio de 6k tokens (metade é um bloco fixo de instruções + FAQ), resposta média 900 tokens no modelo topo de linha. ~30% das perguntas são quase idênticas. Proponha e estime.
Gabarito: (1) Prompt caching do bloco fixo de 3k tokens ⇒ grande parte da entrada passa a custar uma fração; economia relevante já que é 50% do prompt. (2) Cache semântico nas ~30% de perguntas repetidas ⇒ elimina ~30% das chamadas ao LLM. (3) Model routing: classificar a dificuldade; mandar as perguntas simples/repetitivas para um modelo pequeno e barato, reservar o topo de linha para o complexo ⇒ pode cortar 40–60% do custo das que sobram. (4) Cap de saída + formato conciso ⇒ menos tokens de saída (os mais caros). (5) Enxugar a FAQ do prompt para só o relevante via RAG em vez de despejar tudo. Combinado: redução plausível de 50–70%, com qualidade monitorada por eval antes/depois.
Mercado de trabalho: roadmap, entrevistas e portfólio
Objetivo: converter o conteúdo dos módulos anteriores em aprovação — perfis, roadmap, banco de perguntas com respostas e como demonstrar impacto.
10.1 Os perfis que contratam
| Perfil | Foco | Vem de |
|---|---|---|
| Cloud Cost / FinOps Engineer | Implementar as otimizações, automação, dashboards de custo, OpenCost | DevOps/SRE, platform engineering |
| Cloud Economist / Cost Optimization Specialist | Estratégia de commitments, análise de arquitetura para custo, break-even | Cloud sénior + negócio |
| Performance & Efficiency Engineer | Eficiência de compute e de código; custo por unidade de trabalho | Backend/infra com veia de performance |
| AI Infra / LLMOps Engineer | Custo de inferência e treino, GPU, caching, routing (Módulo 9) | ML infra, MLOps |
10.2 Roadmap de estudo (8 semanas)
| Semanas | Foco | Prática |
|---|---|---|
| 1 | Panorama, leitura de fatura, FOCUS, medir antes de cortar (Módulo 1) | Montar um dashboard de custo de uma conta (sua ou de laboratório) |
| 2 | Compute: rightsizing, ARM, autoscaling (Módulo 2) | Fazer rightsizing de uma frota com base em métricas reais e medir |
| 3 | Spot, parking, efêmeros (Módulo 3) | Rodar um job batch em spot com checkpointing; agendar start/stop de dev |
| 4 | Commitments: SP/RI/CUD, cobertura, utilização (Módulo 4) | Análise de portfólio de commitment com recomendação escalonada |
| 5 | Storage e rede (Módulos 5–6) | Configurar lifecycle policies; rastrear e reduzir egress de um cenário |
| 6 | Serverless, gerenciados, warehouse, K8s (Módulos 7–8) | Power tuning de uma Lambda; OpenCost num cluster; otimizar uma query cara |
| 7 | IA/GenAI: tokens, caching, routing, GPU, self-host vs API (Módulo 9) | Instrumentar custo por requisição de um app de LLM e aplicar 3 táticas |
| 8 | Consolidação, medição de impacto, portfólio (Módulo 10) | Publicar um estudo de caso com "antes/depois" e economia mensurada |
10.3 Banco de perguntas de entrevista (com a resposta que aprova)
Júnior/pleno — "Por onde você começa a otimizar custo de nuvem?"
Pela maior categoria e maior serviço da fatura (geralmente compute). Medir utilização real de um período com pico; atacar desperdício e rightsizing primeiro; só depois aplicar descontos (Savings Plan) sobre a base enxuta; e sempre medir o impacto no desempenho depois de cada mudança. Otimizar no chute causa incidente.
Pleno — "RI/Savings Plan: cobertura e utilização"
Cobertura = % do uso elegível protegido por commitment (mirar ~70–85% da base estável, deixando folga). Utilização = % do commitment comprado que é de fato consumido (mirar > 95%). Utilização baixa é pior que on-demand — você paga por algo parado. Preferir Savings Plan (flexível) a RI rígido, salvo carga imóvel; escalonar as compras.
Pleno — "Por que a conta de transferência de dados surpreende?"
Porque o custo se dilui: egress inter-AZ de apps chatty, NAT Gateway cobrado por GB, replicação inter-region, imagens servidas direto do storage. Reduz-se com CDN na frente do que vai a usuários, colocalização do que conversa muito, VPC endpoints para evitar o NAT, compressão, e data locality (processar onde o dado está).
Pleno/sénior — "Quando serverless fica mais caro que contêiner?"
Em carga alta e constante. Serverless ganha em tráfego intermitente/imprevisível (escala a zero, paga por uso). Com throughput alto e estável, poucos contêineres reservados (com Savings Plan) entregam o mesmo trabalho por muito menos. A decisão é uma conta: custo serverless projetado vs N contêineres reservados equivalentes; muitas vezes o ideal é híbrido (base em contêiner, pico em serverless).
Sénior — "Como reduzir o custo de um produto com LLM sem degradar a qualidade?"
Enxugar prompt/contexto e limitar tokens de saída; prompt caching do prefixo estável; cache de resposta / cache semântico para repetições; model routing (fácil → modelo pequeno, difícil → grande); Batch API para trabalho não urgente; escolher o menor modelo que passa no eval da tarefa. No self-host: continuous batching (vLLM/TGI), quantização, autoscaling de GPU. Tudo com qualidade medida antes/depois (LLMOps) e custo por requisição instrumentado.
Sénior — "Self-host de LLM ou API?"
API para volume baixo ou variável, para começar rápido, e quando o custo de engenharia/operação de GPU não compensa. Self-host quando o volume é alto, constante e previsível o suficiente para manter as GPUs bem utilizadas com continuous batching — aí o custo por token cai bem abaixo da API. Pesar também latência, privacidade/compliance e o custo de manter a stack.
Armadilha — "Vamos economizar reduzindo todas as instâncias pela metade"
Corte linear sem medição causa incidente e perda de receita que anula a economia. O caminho é: métricas de utilização reais por serviço (com pico), rightsizing gradual e individual com margem, monitorar latência/erro após cada mudança, e combinar com ARM, autoscaling, spot e commitments. Economia sustentável vem de eliminar desperdício medido, não de aperto uniforme.
10.4 Como demonstrar impacto (portfólio)
- Estudo de caso com números (âncora): pegar um ambiente (real anonimizado, de laboratório, ou dataset de billing público), aplicar um conjunto de otimizações, e documentar o "antes/depois" com a economia mensurada e a prova de que o desempenho não regrediu.
- Automação publicada: um script/pipeline que faz parking de ambientes, ou detecta recursos órfãos, ou gera recomendações de rightsizing a partir de métricas — com o cálculo de economia.
- Análise de commitments: um notebook que, a partir do histórico de uso, recomenda a compra escalonada de Savings Plans com cobertura/utilização projetadas.
- Benchmark de custo/desempenho: a mesma carga em x86 vs ARM, ou em serverless vs contêiner, ou um modelo de LLM antes/depois de quantização — com tabela de custo, latência e qualidade.
- Instrumentação de custo de IA: um gateway simples que registra custo por requisição por modelo/feature e um dashboard de unit economics.
Quatro ideias sustentam a otimização técnica de custos: (1) meça antes de cortar — utilização real, período com pico, impacto no desempenho depois; (2) vá à maior linha primeiro — 20% de compute vale mais que 80% de uma linha pequena; (3) enxugue, depois desconte — rightsizing e faxina antes de commitment; (4) IA tem drivers próprios — token, contexto, GPU e caching, com custo por requisição instrumentado e qualidade medida. As táticas mudam com os SKUs; o método não. A cultura e o processo por trás disso estão na apostila de FinOps.