FinOps
Chega a primeira fatura real do ambiente de produção do BoxOffice, e ela é três vezes a estimativa. Ninguém sabe explicar por quê: os custos estão espalhados em quarenta itens, metade deles com nomes como USE1-NatGateway-Bytes e DataTransfer-Regional-Bytes, e nenhum recurso tem uma tag com o serviço que o criou. Na nuvem, toda decisão de arquitetura é também uma decisão de compra — e a fatura é a única métrica que todo executivo lê.
FinOps (operações financeiras de nuvem) é a prática de trazer responsabilidade financeira ao modelo de gastos variáveis da nuvem, para que engenharia, finanças e negócio façam juntos os trade-offs entre velocidade, custo e qualidade1. Para quem projeta sistemas, isso se resume a três habilidades: estimar quanto uma arquitetura vai custar, atribuir quanto ela de fato custa e otimizar sem quebrar os SLOs2.
O ciclo de vida de FinOps
A FinOps Foundation organiza a prática em três fases que se repetem continuamente1:
flowchart LR
inform["Informar<br/>visibilidade: tags, alocação,<br/>showback, custos unitários"] --> optimize["Otimizar<br/>rightsizing, compromissos,<br/>spot, mudanças de arquitetura"]
optimize --> operate["Operar<br/>orçamentos, alertas de anomalia,<br/>políticas, revisões"]
operate --> inform - Informar — não dá para otimizar o que não se vê. Todo recurso leva tags (
project,env,service,team); os custos do Kubernetes são divididos por namespace e label a partir dos requests de recursos dos pods (ferramentas como o projeto da CNCF OpenCost4, ou o Kubecost). O resultado é o showback (os times veem seus custos) ou o chargeback (os times são cobrados internamente). - Otimizar — reduzir desperdício (recursos ociosos e superdimensionados) e pagar menos por unidade (compromissos, spot, arquiteturas mais baratas).
- Operar — orçamentos com alertas, detecção de anomalias no gasto diário, políticas (nenhum recurso sem tag, nada de instâncias com GPU em dev) e uma revisão mensal de custos ao lado da revisão de SLOs.
Anatomia de uma fatura de nuvem
| Tipo de custo | Cobrado por | Exemplos no BoxOffice | Atenção a |
|---|---|---|---|
| Computação | vCPU-hora e GB-hora (VMs, containers), ou requisição + GB-segundo (FaaS) | Nós do Kubernetes, miniaturas no Lambda | Réplicas ociosas, requests superdimensionados |
| Serviços gerenciados | Hora de instância + armazenamento + I/O | PostgreSQL, Redis, Kafka | Multi-AZ dobra a instância; réplicas se somam |
| Armazenamento | GB-mês, mais requisições | PDFs de ingressos no S3, volumes de banco, snapshots | Snapshots e logs guardados para sempre |
| Transferência de dados | GB movido | Saída da CDN para os fãs, tráfego entre AZs entre serviços, processamento no NAT | Saída para a internet e tráfego entre AZs são cobrados; a entrada geralmente não |
| Itens fixos por hora | Hora, com ou sem uso | Control plane do Kubernetes, load balancers, NAT gateways, endereços IPv4 públicos | Dominam ambientes pequenos e de não produção |
| Observabilidade | GB ingerido, retido, consultado; séries ativas | Logs, métricas, traces | Métricas de alta cardinalidade e logs de debug em produção |
| SaaS de terceiros | Por transação ou por assento | Taxas de pagamento (uma porcentagem do preço do ingresso), e-mail por milhar | Frequentemente maior que toda a infraestrutura — mas é um custo do negócio |
Modelos de preço
| Modelo | Desconto vs on-demand | Compromisso | Bom para |
|---|---|---|---|
| On-demand | — | Nenhum | Cargas em rajadas e desconhecidas; o preço de referência |
| Compromissos (AWS Savings Plans / Reserved Instances, descontos por uso comprometido no GCP, reservas no Azure) | Substancial (frequentemente dezenas de por cento) por 1 ou 3 anos | Pagar por uma base, usando-a ou não | A base constante: os 6 nós sempre ligados, os bancos |
| Spot / preemptível | Grande, variável | Nenhum, mas o provedor pode retomar a capacidade com pouco aviso (dois minutos na AWS) | Trabalho sem estado e interrompível: workers, batch, runners de CI, parte da frota sem estado |
| Serverless / por requisição | — | Nenhum | Tráfego baixo ou com rajadas muito fortes; escala a zero |
O portfólio usual é compromisso para o piso, on-demand para a onda diária, spot para a parte interrompível — o que só funciona se você conhece a sua base, ou seja, depois da fase Informar.
Um modelo de custo do BoxOffice
O modelo abaixo estima a fatura mensal da arquitetura de produção projetada neste curso. Cada número é uma premissa que você pode mudar — esse é o objetivo de um modelo: tornar explícitos os fatores de custo e permitir perguntar "e se?". Os preços são preços de tabela on-demand aproximados da AWS us-east-1; confirme-os na calculadora do provedor antes de citá-los e lembre-se de que outras regiões (incluindo sa-east-1, São Paulo) são mais caras.
Premissas
- Só produção (os ambientes de staging e de teste de carga são extras), rodando 24/7 (730 h por mês).
- Regime normal: 6 nós de trabalho executam todos os serviços. Quatro vendas por mês, cada uma precisando de 24 nós extras por 2 horas.
- Não incluídos: taxas do provedor de pagamento, impostos, planos de suporte, free tiers e descontos, transferência entre AZs entre serviços.
| Component | Palette | Sizing (assumption) | Steady $/month | On-sale extra | Share |
|---|---|---|---|---|---|
| Kubernetes control plane | — | 1 cluster | $73 | $0 | 1% |
| Worker nodes (services) | app | 6 × m6i.xlarge, +24 at peak | $841 | $37 | 17% |
| PostgreSQL primary, Multi-AZ | sql | db.r6g.large ×2 + 2 × 200 GB | $374 | $0 | 7% |
| PostgreSQL read replica | sql | db.r6g.large + 200 GB | $187 | $0 | 4% |
| Redis (primary + replica) | cache | 2 × cache.r6g.large | $301 | $0 | 6% |
| Kafka (managed) | kafka | 3 brokers + 3 × 500 GB | $610 | $0 | 12% |
| Load balancer | lb | 1 ALB, ~5 LCU (×20 at peak) | $46 | $6 | 1% |
| NAT gateways | nat | 3 AZs + 2 TB processed | $189 | $0 | 4% |
| Object storage | objstore | 500 GB tickets and images | $12 | $0 | 0% |
| CDN egress | cdn | 20 TB/month | $1,700 | $0 | 34% |
| Logs ingestion | logs | 1 TB/month | $500 | $0 | 10% |
| Serverless thumbnails | serverless | 2 M runs × 0.5 s × 1 GB | $17 | $0 | 0% |
| Transactional e-mail | email | 1.5 M e-mails | $150 | $0 | 3% |
| Total | $4,999 | $43 | 100% |
Total ≈ $5,042/month. The four on-sales add only $43 because the 24 extra nodes exist for 8 hours; keeping them 24/7 'just in case' would add ≈ $3,364/month. At 400,000 tickets per month the platform costs ≈ $0.013 per ticket sold.
Lendo o modelo
- O pico é barato; a base não. A capacidade elástica para as vendas custa quase nada, porque existe por oito horas. Provisionar para o pico de forma permanente custaria mais que todo o resto da conta de computação. Esse é o argumento econômico para autoscaling, pré-escala e salas de espera (Planejamento de capacidade).
- Serviços de dados dominam a computação. PostgreSQL, Redis e Kafka juntos custam mais que os nós que executam nove serviços. Antes de adicionar um quarto armazenamento de dados, pergunte se um dos existentes não resolve.
- Bytes custam mais que CPUs. A saída da CDN e a ingestão de logs estão entre os maiores itens. Compressão de imagens, tempos de cache mais longos, amostragem de logs de debug e retenção menor mudam a conta mais do que otimizar Java.
- Economia unitária transforma a fatura em uma métrica de negócio: custo por ingresso vendido (ou por 1 000 requisições, por usuário ativo). Uma conta que dobra enquanto os ingressos triplicam é uma boa notícia; uma conta que cresce com os ingressos estáveis é uma regressão — acompanhe-a como uma regressão de desempenho.
Pagar por requisição ou por hora?
Quando FaaS é mais barato que containers sempre ligados? O gráfico compara uma função (100 ms por requisição com 512 MB, atrás de uma porta de entrada HTTP API) com um mínimo de duas pequenas tarefas de container atrás de um load balancer, cada uma atendendo 50 requisições por segundo:
Abaixo de aproximadamente dez requisições por segundo em média, pagar por requisição vence — containers ociosos são puro desperdício. Acima disso, o adicional por requisição se acumula e containers sempre ligados vencem, ainda mais com compromissos. Tráfego em rajadas muda o quadro: o que importa é a média, enquanto os containers precisam ser dimensionados para o pico (ou escalar automaticamente). É por isso que o BoxOffice roda o gerador de miniaturas e os receptores de webhook como funções, e o caminho de compra em containers.
Alavancas de otimização
As alavancas abaixo seguem as práticas de otimização de custo dos frameworks well-architected dos provedores de nuvem3. Cada uma economiza dinheiro e cada uma, exceto a última, pode prejudicar um SLO se aplicada às cegas.
| Alavanca | O que fazer | Efeito típico | Risco para os SLOs |
|---|---|---|---|
| Rightsizing | Definir os requests a partir do uso medido (ex.: p95 de CPU e máximo de memória em duas semanas), não de palpites | Menos nós para os mesmos pods | Apertado demais → throttling e OOMKilled; rode o teste de carga de novo |
| Autoscaling e escala a zero | HPA + autoscaling de nós; escala a zero com KEDA para workers; desligar o staging à noite e nos fins de semana | Horas de não produção: 730 → ~250 por mês | Cold starts; atraso de escala nos picos |
| Compromissos | Cobrir a base medida com compromissos de 1 ano | Preço unitário menor no piso | Pagar por compromisso não usado se a arquitetura mudar |
| Capacidade spot | Rodar workers, CI e uma parte das réplicas sem estado em spot, espalhadas por tipos de instância | Grande desconto nessa parte | Interrupções: exige encerramento gracioso, PDBs, fallback on-demand |
| Instâncias ARM | Nós Graviton/Axion/Ampere para serviços JVM e Python (imagens multi-arquitetura) | Preço menor por vCPU com desempenho semelhante em muitas cargas | Verifique com um benchmark; bibliotecas nativas precisam existir para ARM |
| Reduzir transferência de dados | CDN com TTLs longos; manter serviços conversadores na mesma AZ; VPC endpoints para S3/ECR em vez de NAT | Menos saída e menos processamento no NAT | Afinidade de zona reduz o espalhamento |
| Ciclo de vida do armazenamento | Mover PDFs antigos de ingressos para camadas de acesso infrequente/arquivo; expirar snapshots | Menos GB-mês | Recuperação mais lenta e cobrada |
| Higiene de observabilidade | Amostrar traces, cortar logs de debug em produção, limitar a cardinalidade das métricas, retenção menor | Conta de ingestão menor | Menos detalhe na depuração — mantenha exemplars e traces de erro |
| Apagar recursos ociosos | Volumes soltos, load balancers antigos, clusters de teste esquecidos | Economia pura | Nenhum |
Custo e confiabilidade puxam em direções opostas
Multi-AZ dobra o custo do banco; uma segunda região praticamente dobra tudo. Isso não é desperdício — compra disponibilidade. FinOps não é "gastar menos", é "saber o que cada real compra". Escreva o trade-off no documento de design: "PostgreSQL Multi-AZ custa US$ 187/mês a mais e transforma a falha de uma zona de uma indisponibilidade de várias horas em um failover de um minuto."
Estimando em uma entrevista de system design
Entrevistadores raramente querem dólares, mas consciência de custo é um sinal forte. Um hábito de três passos basta:
- Nomeie os fatores de custo: "O custo é dominado pela saída de imagens (CDN), pela camada de dados e pela computação de pico."
- Ordem de grandeza a partir da sua estimativa de capacidade: "30 nós por 8 horas por mês é barato; 30 nós por 730 horas não é — então fazemos autoscaling e pré-escala."
- Uma otimização com seu trade-off: "Spot para os workers, porque são idempotentes e fazem retry; nunca para o banco primário."
Na entrevista
Perguntas de custo costumam vir disfarçadas: "Precisamos mesmo de Kafka aqui?", "Por que três réplicas?", "Isso poderia ser serverless?". Responda com utilização e razão pico/média: capacidade sempre ligada é mais barata quando está ocupada; preço por requisição é mais barato quando o tráfego é baixo ou muito em rajadas. Mencione que transferência de dados e armazenamentos de dados gerenciados costumam dominar antes da computação.
Boas práticas
- Distribua a conta do cluster pelos requests de recursos, por namespace e label — os nós são compartilhados, então os requests são a chave justa, e são eles que o scheduler reserva.
- Defina um orçamento com alertas em 50%, 80% e 100%, além de um alerta de anomalia no gasto diário — um cluster de teste de carga esquecido aparece em um dia, não na fatura.
- Coloque o custo de uma mudança de projeto no seu documento de projeto, em dólares por mês — "PostgreSQL Multi-AZ: +US$ 187/mês, uma falha de zona vira um failover de um minuto" permite ao revisor julgar o trade-off. No BoxOffice: alavancas de otimização.
- Comprometa-se só até o menor uso dos últimos meses — compromissos são pagos com ou sem uso; o piso é a única parte segura. No BoxOffice: os 6 nós sempre ligados, não os 24 nós da venda (modelo de custos).
- Dê a cada sinal de telemetria a sua própria retenção — traces de erro e métricas de SLO por meses, logs de depuração por dias; ingestão e retenção estão entre as maiores linhas da fatura.
Armadilhas
- Sem tags: custos que não podem ser atribuídos não podem ter dono nem ser otimizados.
- Estimar só a computação: os itens fixos por hora, a transferência de dados e a observabilidade são de onde vêm as surpresas.
- Rightsizing sem teste de carga: a economia aparece na fatura; o throttling aparece no p99 do próximo pico.
- Compromissos antes de medir a base: travar capacidade para uma arquitetura que você está prestes a mudar.
- Ambientes de não produção ligados 24/7: frequentemente uma grande fatia da conta total.
- Otimizar centavos enquanto o NAT gateway processa terabytes: ordene por custo antes de otimizar.
Como se conecta
flowchart LR
BILL["a fatura: compute, serviços gerenciados,<br/>armazenamento, transferência, itens fixos"] --> INF["Informar: tags,<br/>custo por requests dos pods"]
INF --> OPT["Otimizar: rightsizing,<br/>compromissos, spot, ARM"]
OPT --> OPS["Operar: orçamentos,<br/>anomalias, revisão mensal"]
BASE["base vs pico<br/>→ autoscaling, pré-escala"] --> OPT
FAAS["por requisição vs por hora<br/>→ equilíbrio do serverless"] --> OPT
UNIT["unit economics:<br/>custo por ingresso vendido"] --> OPS
OPT --> SLO["toda alavanca pode ferir um SLO<br/>→ Confiabilidade"]
OPT --> LT["rode o teste de carga de novo<br/>→ Performance"]
BILL --> MAZ["Multi-AZ, segunda região:<br/>custo que compra disponibilidade"]
BILL --> OBS["fatura de observabilidade:<br/>cardinalidade, retenção"] Componentes da paleta: sql · cache · kafka (a camada de dados domina o compute) · cdn (egress) · nat (fixo por hora + por GB processado) · objstore (camadas de ciclo de vida) · logs (ingestão) · serverless · worker (candidatos a spot) · payment (taxas, um custo do negócio). Cenários: serverless-burst, multi-region (quanto custa uma segunda região). Continua em: Compute — containers ou serverless, Performance — planejamento de capacidade, Confiabilidade — recuperação de desastres, Redes e segurança — a rede na nuvem (NAT gateways), Observabilidade — sinais (cardinalidade), Projeto — relatório de custos.
-
FinOps Foundation. FinOps Framework. ↩↩
-
STORMENT, J. R.; FULLER, M. Cloud FinOps. 2nd ed. O'Reilly, 2023. ↩
-
AWS. Well-Architected Framework — Cost Optimization Pillar. ↩
-
OpenCost. Open source cost monitoring for cloud-native environments (projeto da CNCF). ↩