Post-mortem: o dashboard de BI que virou a maior linha da fatura em três dias

Escrito por

em

Cenário: um data warehouse na nuvem rodando em uma região, a ferramenta de BI hospedada em outra, e um dashboard comercial com atualização automática a cada cinco minutos para cerca de quarenta pessoas. Numa sexta à tarde alguém trocou o filtro padrão do dashboard de “últimos 30 dias” para “todo o histórico”. Na segunda de manhã, a fatura parcial da conta acusava um valor de transferência de dados de saída maior que o custo mensal inteiro da infraestrutura — algo na casa das dezenas de milhares de reais acumuladas em pouco mais de setenta horas.

O relato abaixo é reconstruído para ilustrar o modo de falha, não descreve a operação de nenhuma empresa específica e os valores servem apenas para dar ordem de grandeza. O padrão, porém, aparece em qualquer arranjo onde o motor de consulta e o consumidor dos dados vivem em zonas, regiões ou provedores diferentes — e ele não dispara nenhum alerta técnico enquanto está acontecendo.

A conta chega três dias depois do erro

O que torna esse tipo de incidente caro não é a magnitude do erro, é a defasagem entre causa e sinal. Uma queda de serviço se manifesta em segundos: o health check falha, o alerta dispara, alguém acorda. Um vazamento de custo se manifesta no fechamento da fatura, e a maioria dos provedores consolida o uso de rede com atraso de horas — em alguns casos, mais de um dia.

Durante todo o fim de semana, cada métrica que o time observava estava verde. CPU do warehouse dentro da média, porque o motor era serverless e escalava sozinho. Latência do dashboard estável, porque a consulta continuava respondendo em poucos segundos. Taxa de erro em zero. Não houve degradação: o sistema fez exatamente o que foi pedido, quarenta vezes por hora, durante três dias, movendo um resultado de consulta inteiro pela internet pública a cada execução.

A descoberta veio pelo financeiro, não pela engenharia. Esse detalhe é o diagnóstico real do incidente. Se o primeiro a perceber um problema de infraestrutura é quem paga a fatura, o problema não foi o filtro do dashboard — foi a ausência de qualquer sinal de custo dentro do ciclo de observabilidade do time.

Há um agravante estrutural nesse tipo de defasagem: o console de faturamento da nuvem não é uma ferramenta de engenharia. Ele agrega por serviço e por conta, raramente por consulta, quase nunca por usuário. Quando o time finalmente abre o relatório de custo, encontra uma linha chamada “transferência de dados” com um valor grande e nenhuma pista de qual carga a produziu. Reconstruir a origem exige cruzar log de auditoria do warehouse com log de acesso do BI, o que costuma levar mais tempo que a correção em si.

Egress é métrica de consulta, não de infraestrutura

Times de plataforma instrumentam recursos: contêiner, nó, fila, banco. Transferência de saída não pertence a nenhum recurso. Ela é o produto de quatro variáveis que ninguém observa junto: tamanho do resultado da consulta, número de consumidores, frequência de atualização e distância de rede entre origem e destino.

Nesse caso, as quatro pioraram ao mesmo tempo por causa de uma única mudança. Trocar a janela de tempo do filtro multiplicou o tamanho do resultado por duas ordens de grandeza. O cache da ferramenta de BI estava configurado por usuário e por combinação de filtros, então quarenta pessoas com o dashboard aberto significavam quarenta execuções independentes, não uma. O refresh automático de cinco minutos manteve o ciclo rodando à noite e no fim de semana, com as abas abertas em máquinas que ninguém desligou. E o cruzamento de região transformou o que seria tráfego interno gratuito em tráfego cobrado por gigabyte.

Nenhuma dessas quatro decisões é errada isoladamente. Cache por usuário existe porque filtros diferentes produzem resultados diferentes. Refresh curto existe porque o time comercial queria ver pedido entrando. Separar BI e warehouse em regiões distintas costuma ser herança de migração, não escolha deliberada. O custo aparece na multiplicação, e a multiplicação não tem dono.

Onde o custo se acumula sem aparecer

Vale mapear os padrões recorrentes antes de discutir correção, porque o mesmo mecanismo se repete em contextos que nada têm a ver com BI.

Padrão de acesso Por que vaza O que costuma resolver
Dashboard com auto-refresh Resultado completo trafega por usuário, por ciclo, inclusive fora do horário comercial Cache compartilhado por consulta e refresh sob demanda em vez de temporizado
Exportação agendada de CSV Job diário puxa a tabela inteira quando só o delta mudou Extração incremental por marca d’água de atualização
Réplica entre regiões Replicação contínua de tabelas que ninguém lê na região secundária Replicar apenas o subconjunto efetivamente consultado
Ambiente de staging apontando para produção Consultas de teste percorrem o mesmo caminho de rede cobrado Amostra local do dataset, não espelho remoto
Serviço em nuvem A lendo storage em nuvem B Toda leitura é saída cobrada, mesmo interna à aplicação Colocar processamento junto do dado ou cachear na borda

O denominador comum é o mesmo: alguém desenhou o fluxo assumindo que ler dado é barato. Dentro da mesma zona, quase é. Atravessando fronteira de rede, o preço por gigabyte multiplica por um volume que cresce sozinho conforme o negócio cresce.

Vale notar o que não resolve: comprimir o resultado. Compressão reduz o volume trafegado por execução, mas não toca no número de execuções, que é o termo que cresce sozinho. Um resultado três vezes menor rodando quarenta vezes por hora continua sendo um problema de multiplicação. A ordem correta de ataque é sempre frequência primeiro, número de consumidores depois, tamanho por último — o inverso da intuição de quem chega ao problema pelo lado da rede.

O que teria cortado o prejuízo no primeiro dia

Três controles independentes, e qualquer um deles sozinho teria limitado o dano a algumas centenas de reais em vez de dezenas de milhares.

O primeiro é orçamento com janela diária. A maioria dos times configura alerta de orçamento mensal com limiar percentual, o que significa descobrir o estouro quando já se gastou boa parte do mês. Um alerta sobre gasto acumulado nas últimas 24 horas comparado à média das duas semanas anteriores teria disparado no sábado de manhã.

O segundo é teto de bytes por consulta no próprio motor. Vários warehouses permitem rejeitar a execução de qualquer consulta que ultrapasse um volume declarado de leitura, e isso é preferível a descobrir depois: o dashboard teria quebrado na sexta às 16h, com uma mensagem de erro clara e um responsável óbvio.

Em BigQuery, o teto é uma propriedade do job e vale ser aplicado por padrão na conexão de BI, não caso a caso:

bq query --maximum_bytes_billed=10000000000 \
  --use_legacy_sql=false \
  'SELECT ... FROM vendas WHERE data >= @inicio'

Motores diferentes expõem o mesmo controle com outro nome — em Snowflake, o caminho é limitar o tamanho do warehouse virtual somado a STATEMENT_TIMEOUT_IN_SECONDS. O princípio não muda: falhar rápido custa menos que responder devagar.

O terceiro é cache compartilhado no BI. Trocar o cache por usuário por cache por assinatura de consulta faz quarenta execuções virarem uma, e o ganho não é só de rede: reduz também a concorrência no warehouse no horário de pico. A objeção usual é controle de acesso por linha, que de fato impede compartilhar resultado entre perfis diferentes. Nesse caso, a solução é segmentar o cache por papel, não por pessoa.

Próximo passo: os três guardrails que cabem numa sprint

Se a operação tem qualquer fluxo de dados atravessando região ou provedor, três itens valem entrar no backlog agora, nessa ordem.

  • Inventário de travessias. Liste todo par origem-destino em que o dado sai de uma região e entra em outra. Bastam meia dúzia de perguntas ao time: onde está o warehouse, onde está o BI, onde estão os buckets, onde roda o ETL, onde ficam os backups.
  • Alerta de derivada, não de teto. Configure notificação sobre variação do gasto diário em relação à linha de base, e não apenas sobre o valor absoluto do mês. Vazamento de custo é sempre uma inflexão de curva antes de ser um número grande.
  • Limite duro no motor de consulta. Defina teto de bytes lidos ou timeout na conexão usada por ferramentas de terceiros. Ferramenta de BI é a superfície onde alguém sem contexto de infraestrutura consegue disparar uma consulta arbitrária.

O item que costuma gerar mais resistência é o terceiro, porque quebra dashboard de gente que reclama alto. Vale quebrar mesmo assim. Um dashboard que só funciona lendo o histórico inteiro a cada cinco minutos não é um dashboard — é um job de ETL disfarçado, e deveria ser materializado como tabela agregada em vez de recalculado a cada abertura de aba.

Comentários

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *