A jornada da CERC para sair do BigQuery on-demand, reduzir custo sem sacrificar resiliência
TL;DR — Na CERC, saímos do BigQuery on-demand depois que um erro humano gerou cinco horas de queries contínuas e um impacto severo de custo. A partir desse incidente, redesenhamos a operação com foco em simplicidade, eficiência operacional e resiliência: primeiro com reservas por ambiente, depois testando e descartando um autoscaling próprio que não trouxe o ganho de performance esperado, e em seguida adotando capacidade fixa com compromisso anual, reduzindo os custos em 40%. Mais tarde, refinamos o modelo para isolar workloads críticos com uma reserva regulatória, capaz de usar idle slots de outras reservas e autoscaling apenas em janelas específicas. O resultado foi uma operação mais previsível, mais eficiente e melhor alinhada à criticidade dos nossos processos.
A jornada da CERC para sair do BigQuery on-demand, reduzir custo sem sacrificar resiliência
Em engenharia de plataforma, quase toda escolha boa tem prazo de validade.
O modelo que resolve bem o problema de hoje pode se tornar arriscado quando a empresa cresce, quando a operação fica mais sensível ou quando o erro deixa de ser apenas um inconveniente e passa a ter impacto financeiro real.
Foi exatamente isso que vivemos na CERC com BigQuery.
No início, operávamos no modelo on-demand. Para o estágio em que estávamos, a escolha fazia sentido: era simples, exigia pouca maturidade operacional e evitava a necessidade de dimensionar capacidade desde cedo.
Funcionou. Até o dia em que não funcionou mais.
Uma falha humana, em março de 2022, fez com que consultas fossem executadas continuamente por cerca de cinco horas. O resultado foi um billing catastrófico. Em poucas horas, duplicamos nossa fatura de cloud e aprendemos da forma mais cara possível uma lição importante: conveniência sem previsibilidade cobra juros.
A partir daí, nossa pergunta mudou.
Não era mais “como usar BigQuery?”. Era “como operar BigQuery de forma compatível com o nível de controle, resiliência e eficiência que a CERC precisa?”.
As três premissas que guiaram o redesenho
Depois do incidente, definimos três critérios para avaliar qualquer nova arquitetura:
- Simplicidade: o desenho precisava ser claro o suficiente para ser operado com segurança.
- Eficiência operacional: não queríamos trocar risco financeiro por uma operação complexa demais.
- Resiliência: workloads críticos precisavam continuar executando com previsibilidade.
Essas premissas parecem óbvias. O problema é que, quando a pressão aparece, é comum sacrificar uma delas sem perceber.
Nós tentamos não fazer isso.
Visão geral da evolução
Fase 1: o conforto do on-demand
O modelo on-demand nos entregava três vantagens claras:
- zero necessidade de planejar slots;
- baixa complexidade de operação;
- velocidade de adoção.
Para uma empresa em ascensão e ainda amadurecendo em cloud, isso era extremamente útil.
Mas o modelo também escondia um risco: ele desloca a preocupação de capacidade, mas não elimina a preocupação de previsibilidade. Quando uma carga sai do padrão, a conta pode sair junto.
Foi isso que o incidente nos mostrou de forma muito objetiva.
Fase 2: reservas por ambiente
A primeira resposta foi migrar para o modelo de reservas.
Criamos um projeto dedicado para concentrar os slots e segmentamos a capacidade em quatro reservas principais:
1) Staging
Ambiente de testes internos, com menos slots. Aqui a prioridade era eficiência de custo. Queries mais lentas eram aceitáveis.
2) Homologação
Ambiente mais sensível à lentidão porque concentra operações de homologação de clientes. Recebeu uma capacidade maior.
3) Produção
Ambiente com maior necessidade de poder computacional, velocidade e previsibilidade. Também habilitamos o uso de idle slots vindos de outras reservas.
4) All
Reserva com poucos slots para uso exploratório da organização. Ela também servia como uma espécie de “rede de contenção” para evitar que novos projetos surgissem fora do modelo de governança.
O que essa mudança resolveu
Com esse desenho, deixamos de ter consumo aberto e passamos a operar em um intervalo pré-definido de capacidade. Ganhamos:
- previsibilidade de custo;
- isolamento básico entre contextos;
- mais controle sobre a plataforma.
Naquele momento, parecia que o problema estava resolvido.
Não estava.
Fase 3: a hipótese que parecia certa
Depois de migrar para reservas, surgiu uma ideia quase intuitiva:
Se slots representam capacidade computacional, então aumentar slots dinamicamente deve acelerar as queries.
Com base nessa hipótese, criamos um autoscaling próprio.
A lógica era simples:
- monitorar o uso de slots em produção;
- aumentar a capacidade quando o consumo se aproximasse do pico;
- desalocar slots quando a pressão diminuísse.
No papel, parecia um desenho elegante. Dinâmico. Inteligente. E economicamente eficiente.
Na prática, os custos continuaram altos.
Foi aí que resolvemos testar a hipótese em vez de continuar assumindo que ela era verdadeira.
Fase 4: desligamos o autoscaling — e nada piorou
Desabilitamos o nosso mecanismo de scaling e passamos a operar com uma quantidade fixa de slots.
Esperávamos ver degradação de performance.
Ela não veio.
As queries não ficaram materialmente mais lentas.
Esse foi um dos pontos mais importantes da jornada, porque desmontou uma premissa que parecia bastante razoável. Não conseguimos afirmar com certeza absoluta a causa exata, já que o comportamento interno de slots no BigQuery é proprietário. Mas nossas hipóteses passaram a girar em torno de dois pontos:
- pode existir algum custo de ativação, ou “cold start”, quando novos slots entram em cena;
- parte relevante das cargas não era paralelizável a ponto de se beneficiar linearmente do aumento de slots.
O efeito prático
Tomamos uma decisão simples: remover o autoscaling próprio da arquitetura.
Isso trouxe dois benefícios imediatos:
- simplificou a operação;
- reduziu o custo.
Com a capacidade fixa, passamos a comprar slots em compromisso anual e reduzimos os custos de BigQuery em 40%.
Esse foi um aprendizado valioso: às vezes, a melhor otimização é parar de “otimizar” em excesso.
Fase 5: um novo problema apareceu — o vizinho barulhento
Um ano depois, percebemos outra limitação do desenho.
Nossas reservas estavam separadas por ambiente, não por criticidade de processo.
Na prática, isso significava que projetos diferentes de produção podiam disputar os mesmos slots. Para cargas comuns, isso já era ruim. Para cargas regulatórias, isso era perigoso.
O risco aqui não era só lentidão. Era estouro de janelas críticas.
A solução foi criar uma nova reserva: a reserva regulatória.
Nela, concentramos todos os processos regulatórios em um projeto próprio, com precedência operacional em relação às demais cargas.
O que mudou com isso
Passamos a isolar a carga certa com o critério certo.
Não era mais apenas “produção versus homologação”. Agora era:
- workloads críticos com reserva própria;
- workloads menos sensíveis compartilhando outra camada de capacidade.
Esse ajuste parece pequeno, mas muda completamente a forma como a plataforma responde à concorrência interna.
Fase 6: a volta do scaling, agora orientado por janela
Mesmo com a reserva regulatória, havia uma pergunta importante:
como ampliar capacidade nos momentos críticos sem voltar ao erro do scaling contínuo?
A resposta foi reintroduzir scaling, mas com outro racional.
Em vez de alocar e desalocar slots o tempo todo com base em uso momentâneo, passamos a expandir capacidade em janelas regulatórias pré-definidas.
Ou seja:
- antes da janela crítica, aumentamos os slots;
- durante a execução, mantemos a capacidade extra;
- ao final, reduzimos novamente.
E havia mais um refinamento.
Se o processo regulatório terminasse antes do previsto, a própria aplicação publicava uma mensagem em Pub/Sub avisando que os slots adicionais podiam ser removidos.
O scaling deixou de responder a ruído de consumo e passou a responder a um evento real de negócio.
Fase 7: BigQuery Editions mudou o problema de novo
Quando o BigQuery Editions entrou em cena, tivemos que redesenhar a operação mais uma vez.
O produto passou a oferecer autoscaling nativo, mas em uma economia de custos diferente da anterior. Então a pergunta deixou de ser “podemos escalar?” e passou a ser “em que ordem a capacidade deve ser consumida?”.
Nosso desenho final seguiu esta lógica:
- usar os slots pré-alocados da própria reserva regulatória;
- se isso não bastar, usar idle slots de outras reservas;
- apenas na ausência desses dois, recorrer ao autoscaling nativo.
Por que essa ordem importa
Porque ela transforma o autoscaling em último recurso, e não em comportamento padrão.
Esse detalhe é essencial. Se você deixa o autoscaling agir livremente o tempo inteiro, existe o risco de passar a operar continuamente em capacidade expandida — e perder justamente a previsibilidade que tentou conquistar.
Por isso, mesmo no modelo Editions, continuamos usando o mesmo princípio anterior: o teto de autoscaling é elevado apenas em janelas pré-definidas e reduzido em seguida.
Como implementamos isso
Toda essa operação foi descrita com Terraform e YAML.
Em vez de depender de configuração manual ou conhecimento tácito, passamos a codificar as decisões mais importantes da plataforma:
- capacidade base;
- uso ou não de idle slots;
- limites de autoscaling;
- assignees por projeto.
Um exemplo simplificado de configuração:
reservation-regulatory:
slot_capacity: 100
ignore_idle_slots: false
autoscale_max_slots: 1400
assignees:
- id: projects/<project_name>
E o Terraform que materializa esse padrão:
resource "google_bigquery_reservation" "reservations" {
provider = google-beta
for_each = local.reservations
project = each.value.project_id
name = each.value.name
location = each.value.location
edition = each.value.edition
concurrency = each.value.concurrency
ignore_idle_slots = each.value.ignore_idle_slots
slot_capacity = each.value.slot_capacity
scaling_mode = each.value.scaling_mode
max_slots = each.value.max_slots
dynamic "autoscale" {
for_each = each.value.autoscale_max_slots != null ? [true] : []
content {
max_slots = each.value.autoscale_max_slots
}
}
lifecycle {
ignore_changes = [autoscale[0].max_slots]
}
}
O ganho aqui não foi só automação. Foi consistência operacional.
O que aprendemos
Se precisássemos resumir a jornada em alguns pontos, seriam estes:
1) O modelo inicial certo pode deixar de ser o modelo certo
On-demand foi útil no estágio em que a empresa estava. O erro teria sido insistir nele depois que a operação mudou.
2) Hipóteses intuitivas de performance precisam ser testadas
“Mais slots = mais velocidade” parecia óbvio. Não era.
3) Isolamento por ambiente não basta para cargas com criticidades diferentes
Em algum momento, a unidade de isolamento precisa refletir o processo de negócio.
4) Autoscaling não é automaticamente sinônimo de maturidade
Sem contexto operacional, ele pode virar apenas uma forma cara de esconder ineficiência.
5) Eficiência real nasce do equilíbrio entre custo, simplicidade e resiliência
Se um desenho melhora um desses pontos destruindo os outros dois, ele provavelmente ainda não está maduro.
O que essa jornada mudou na nossa plataforma
Na CERC, essa jornada com BigQuery não foi apenas a troca de um modelo de cobrança por outro.
Ela foi a evolução de uma plataforma de dados rumo a uma operação mais intencional.
Começamos com conveniência. Passamos por um incidente. Construímos uma primeira resposta. Derrubamos uma hipótese que parecia correta. Reduzimos custo. Refinamos o isolamento. Reintroduzimos elasticidade no lugar certo. E, ao final, chegamos a um desenho melhor não por ser mais sofisticado, mas por estar mais alinhado à forma como a operação realmente funciona.
Esse tipo de resultado dificilmente aparece de uma vez só.
Ele aparece quando um time de plataforma aceita revisitar premissas, simplificar o que ficou complexo demais e redesenhar a fundação antes que o sistema cobre caro por isso.
Quer trabalhar em problemas como esse?
O Centro de Excelência em Infraestrutura da CERC existe para construir as plataformas que permitem que a empresa cresça com eficiência, ordem e resiliência. Isso significa projetar a base sobre a qual aplicações, times e operações críticas evoluem com segurança, previsibilidade e autonomia.
É o tipo de trabalho em que arquitetura não fica apenas no diagrama. Ela impacta custo, desempenho, governança, risco operacional e a capacidade de a empresa escalar sem perder controle.
Se você gosta de construir plataformas, automatizar operações, desenhar sistemas resilientes e tomar decisões de engenharia com impacto real, esse é exatamente o tipo de desafio que enfrentamos por aqui.
A CERC opera a infraestrutura do mercado financeiro brasileiro para registro de recebíveis — um sistema onde correção, escala e confiabilidade não são opcionais. Construímos a plataforma de dados sobre a qual o sistema financeiro roda. Se você quer trabalhar em problemas como este — escala real, consequências reais e autonomia para projetar a solução certa — estamos contratando.
Este post foi escrito pelo time do Centro de Excelência em Infraestrutura: Felipe Trucolo, Demetrius Moro e André Santos.