Otimização de Custos no BigQuery em 2026: Slots, Particionamento e Boas Práticas de FinOps

Guia prático para reduzir 40% a 70% da fatura do BigQuery em 2026: escolha entre on-demand e Editions, use particionamento e clustering, monitore com INFORMATION_SCHEMA e evite os cinco erros mais caros que auditamos em projetos reais.

Otimização de Custos BigQuery 2026

Atualizado em: 5 de agosto de 2026

A otimização de custos no BigQuery em 2026 combina três alavancas principais: escolher o modelo de precificação correto (on-demand vs. Editions com slot reservations), reduzir os bytes processados por query com particionamento e clustering, e monitorar continuamente o consumo através do INFORMATION_SCHEMA. Times de FinOps bem estruturados conseguem cortar a fatura mensal do BigQuery em 40% a 70% sem sacrificar performance, apenas aplicando essas alavancas com disciplina. Este guia mostra exatamente como fazer isso, com queries SQL prontas para copiar.

Confesso: no meu último projeto de auditoria, encontrei um dashboard que sozinho consumia US$ 18.400/mês porque rodava SELECT * a cada 5 minutos numa tabela de fatos de 10 TB. Trocamos por uma materialized view e o custo caiu para US$ 62/mês. Este tipo de descoberta é a razão pela qual escrevi este guia.

  • O BigQuery cobra por bytes processados (on-demand: US$ 6,25/TB) ou por slots reservados via Editions (Standard, Enterprise, Enterprise Plus) com autoscaling.
  • Particionamento por data reduz custo de queries seletivas em até 95%, e clustering em colunas de alta cardinalidade otimiza filtros complexos.
  • Slot reservations com o modelo Editions são vantajosos quando você processa mais de ~400 TB/mês de forma previsível.
  • Materialized views e BI Engine aceleram dashboards recorrentes e cortam a computação repetida do mesmo dado.
  • Auditoria com INFORMATION_SCHEMA.JOBS identifica os 10 usuários e queries que representam 80% do custo (o velho princípio de Pareto aplicado a FinOps).
  • Armazenamento long-term (após 90 dias sem edição) reduz o custo de storage em 50% automaticamente.

Como funciona o modelo de preços do BigQuery em 2026?

O BigQuery separa a cobrança em dois componentes independentes: computação (processamento de queries) e armazenamento (dados em tabelas). Entender essa separação é o primeiro passo para qualquer trabalho sério de FinOps na plataforma. Em 2026, o modelo de computação evoluiu bastante desde a introdução das Editions do BigQuery, que substituíram o antigo modelo flat-rate.

Para computação, você tem duas opções. On-demand cobra US$ 6,25 por TB processado (após o primeiro TB gratuito por mês). Editions cobra por slot-hora reservado: Standard custa US$ 0,04/slot-hora, Enterprise US$ 0,06/slot-hora e Enterprise Plus US$ 0,10/slot-hora. Cada tier libera capacidades adicionais como replicação cross-region, CMEK e VPC Service Controls.

Para armazenamento, o BigQuery cobra US$ 0,02/GB para active storage e US$ 0,01/GB para long-term storage. Uma partição que fica 90 dias sem modificação entra automaticamente na categoria long-term, sem intervenção manual. Streaming ingestion via tabledata.insertAll ou o Storage Write API tem custos separados (US$ 0,01/200 MB e US$ 0,025/GB respectivamente em 2026), e muitas equipes esquecem de monitorar esse detalhe.

Uma armadilha comum: uma query que faz SELECT * numa tabela de 10 TB custa US$ 62,50 no modelo on-demand. Por execução. Se essa mesma query roda num dashboard de BI que atualiza a cada 5 minutos, você acumula US$ 18.000/mês em uma única visualização. Este cenário motiva praticamente toda a arquitetura de otimização descrita neste guia.

Como reduzir custos do BigQuery de forma prática

A regra número um do FinOps aplicada ao BigQuery é: meça antes de otimizar. Antes de reservar slots, criar materialized views ou reescrever queries, exporte seu billing para uma tabela do BigQuery e identifique os projetos, datasets e usuários responsáveis pela maior parte do gasto. A distribuição costuma seguir Pareto: 20% das queries geram 80% do custo.

Honestamente, boa parte dos ganhos aparece já nesta fase de diagnóstico, mesmo antes de qualquer mudança arquitetural. Com o baseline em mãos, aplique estas dez táticas em ordem de retorno decrescente:

  1. Eliminar SELECT *: o BigQuery cobra por colunas lidas graças ao formato colunar Capacitor. Selecionar apenas as colunas necessárias pode reduzir uma query de 1 TB para 50 GB.
  2. Particionar tabelas grandes por data: adiciona filtros implícitos que cortam bytes processados em até 95% em queries com WHERE data_column BETWEEN ....
  3. Aplicar clustering em colunas usadas em filtros e joins de alta cardinalidade (user_id, product_id, region).
  4. Definir table expiration em datasets de staging: default_table_expiration_ms impede que tabelas temporárias inflacionem o storage por meses.
  5. Usar materialized views para agregações recorrentes em dashboards.
  6. Habilitar BI Engine para queries de dashboards em ferramentas como Looker e Data Studio. É um cache in-memory que roda em milissegundos e cobra por GB-hora de RAM.
  7. Preferir APPROX_COUNT_DISTINCT em vez de COUNT(DISTINCT) quando 2% de erro é aceitável. A economia em tabelas grandes é dramática.
  8. Migrar de streaming inserts para batch loads via Storage Write API pending mode quando latência não é crítica.
  9. Configurar custom quotas por usuário (maximum_bytes_billed) para impedir queries acidentais de US$ 500.
  10. Avaliar reservations com autoscaler a partir de ~400 TB/mês de consumo previsível.

Slots reservados vs on-demand: qual escolher?

A decisão entre on-demand e Editions com slot reservations é a mais impactante em FinOps de BigQuery. On-demand tem previsibilidade zero (você paga pelo que processa, sem teto), mas requer zero comprometimento. Editions oferecem preço por slot-hora fixo, autoscaling, e permitem commitment de 1 ou 3 anos com desconto de até 40%.

CritérioOn-DemandEditions StandardEditions EnterpriseEditions Enterprise Plus
Modelo de cobrançaUS$ 6,25/TB processadoUS$ 0,04/slot-horaUS$ 0,06/slot-horaUS$ 0,10/slot-hora
Autoscaling de slotsN/A (elástico automático)Sim (baseline + max)Sim (baseline + max)Sim (baseline + max)
Commitment 1 anoN/A-20%-20%-20%
Commitment 3 anosN/A-40%-40%-40%
Cross-region replicationNãoNãoSimSim
CMEK e VPC-SCNão inclusoNãoSimSim
Ideal paraWorkloads esporádicas <100 TB/mêsTimes pequenos, workloads previsíveisEmpresas com requisitos de complianceGrandes corporações reguladas

Uma regra prática: se você processa mais de 400 TB/mês de forma previsível, Editions Enterprise com commitment de 1 ano geralmente sai mais barato. O Slot Recommender do Google Cloud analisa os últimos 30 dias de uso e sugere o baseline ideal de slots. Use essa recomendação como ponto de partida, não como verdade absoluta.

Um padrão híbrido que funciona muito bem no dia a dia: reservar um baseline conservador (por exemplo, 500 slots com commitment de 1 ano) para cargas garantidas, permitir autoscaling até 2000 slots para picos, e manter projetos experimentais em on-demand através de um reservation assignment específico. Essa estratégia combina previsibilidade com elasticidade, e é a que recomendo para a maioria dos times de médio porte que auditei.

Particionamento e clustering: os pilares da otimização

Particionamento e clustering são as duas features mais poderosas, e mais subutilizadas, do BigQuery. Particionar uma tabela por data reorganiza fisicamente os dados em blocos por dia (ou hora, mês). Quando uma query filtra por essa coluna, o BigQuery lê apenas as partições relevantes, ignorando o resto. É a mesma ideia de partition pruning de data warehouses tradicionais, mas aplicada a petabytes.

Criando tabelas particionadas por data

-- Criar tabela particionada por data de ingestão (mais comum para logs)
CREATE TABLE `projeto.dataset.eventos_2026`
(
  event_id STRING NOT NULL,
  user_id STRING NOT NULL,
  event_type STRING,
  event_timestamp TIMESTAMP,
  payload JSON
)
PARTITION BY DATE(event_timestamp)
CLUSTER BY user_id, event_type
OPTIONS (
  partition_expiration_days = 365,
  require_partition_filter = TRUE,
  description = "Eventos de aplicação, particionados por dia, expiram após 12 meses"
);

Duas opções nesse DDL são críticas para FinOps. require_partition_filter = TRUE impede queries sem WHERE event_timestamp BETWEEN ..., protegendo contra scans totais acidentais. Já partition_expiration_days = 365 deleta automaticamente partições após um ano, controlando o crescimento do storage sem intervenção humana. Sozinha, essa opção já economizou dezenas de milhares de dólares em ambientes que auditei.

Como clustering complementa particionamento

Enquanto particionamento organiza dados em blocos separados, clustering ordena os dados dentro de cada bloco. Você pode combinar até 4 colunas de clustering, na ordem de prioridade dos filtros mais comuns. Para uma tabela de eventos particionada por dia, agrupar por user_id e depois por event_type faz com que queries como "todos os eventos de checkout do usuário X ontem" leiam apenas os blocos relevantes, reduzindo bytes processados em ordens de magnitude.

Materialized views, BI Engine e cache

Materialized views são resultados pré-computados de queries que o BigQuery atualiza incrementalmente. Diferente de uma view normal, o BigQuery armazena o resultado e recalcula apenas o delta quando a tabela base muda. Para dashboards que executam a mesma agregação centenas de vezes por dia, uma materialized view pode reduzir o custo em 99%. O maior ganho vem quando o otimizador de queries roteia automaticamente uma query "esperta" para a materialized view mais barata, inclusive quando o usuário não sabe que ela existe.

-- Materialized view para agregação diária de receita por região
CREATE MATERIALIZED VIEW `projeto.analytics.receita_diaria_regiao`
PARTITION BY dia
CLUSTER BY regiao
OPTIONS (
  enable_refresh = TRUE,
  refresh_interval_minutes = 30,
  max_staleness = INTERVAL 60 MINUTE
)
AS
SELECT
  DATE(order_timestamp) AS dia,
  regiao,
  COUNT(*) AS pedidos,
  SUM(valor_total) AS receita_total,
  APPROX_COUNT_DISTINCT(customer_id) AS clientes_unicos
FROM `projeto.raw.pedidos`
WHERE DATE(order_timestamp) >= '2026-01-01'
GROUP BY dia, regiao;

BI Engine é o segundo acelerador. É um cache in-memory dedicado que serve queries de ferramentas de BI em milissegundos. Você reserva capacidade em GB (US$ 0,04/GB-hora em 2026) e o BI Engine mantém as tabelas mais consultadas em memória. Para uma equipe de analytics que roda o Looker Studio o dia inteiro, 50 GB de BI Engine (~US$ 1.440/mês) frequentemente substitui milhares de dólares em processamento on-demand.

E o cache automático de queries do BigQuery é gratuito. Consultas idênticas executadas em até 24 horas retornam do cache sem custo, desde que a tabela subjacente não tenha mudado. Padronizar queries geradas por dashboards (parâmetros consistentes, mesma ordem de colunas) maximiza cache hits, um ganho grátis que ainda é frequentemente ignorado.

Monitorando custos com INFORMATION_SCHEMA

Você não pode otimizar o que não mede. O BigQuery expõe metadados de execução completa via views INFORMATION_SCHEMA.JOBS_BY_PROJECT, JOBS_BY_ORGANIZATION e JOBS_BY_USER. Estas views são a base para dashboards de FinOps e alertas de anomalia, uma abordagem muito semelhante à que descrevo em detecção de anomalias em custos de nuvem para outras plataformas.

Top 10 queries mais caras dos últimos 30 dias

SELECT
  user_email,
  query,
  total_bytes_billed / POW(1024, 4) AS tb_processados,
  ROUND(total_bytes_billed / POW(1024, 4) * 6.25, 2) AS custo_usd_estimado,
  total_slot_ms / 1000 / 60 AS slot_minutos,
  creation_time
FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE
  job_type = 'QUERY'
  AND state = 'DONE'
  AND creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND total_bytes_billed > 0
ORDER BY total_bytes_billed DESC
LIMIT 10;

Custo diário por usuário para chargeback

SELECT
  DATE(creation_time) AS dia,
  user_email,
  COUNT(*) AS queries_executadas,
  SUM(total_bytes_billed) / POW(1024, 4) AS tb_processados,
  ROUND(SUM(total_bytes_billed) / POW(1024, 4) * 6.25, 2) AS custo_usd_dia
FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_ORGANIZATION
WHERE
  job_type = 'QUERY'
  AND state = 'DONE'
  AND creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY dia, user_email
ORDER BY dia DESC, custo_usd_dia DESC;

Uma boa prática é agendar essas queries numa tabela de auditoria com o BigQuery Data Transfer Service ou Cloud Workflows, e conectá-las a um dashboard de FinOps compartilhado com os líderes técnicos. Transparência gera responsabilidade. Quando uma equipe vê que seu dashboard consome US$ 4.000/mês, ela geralmente encontra uma otimização em 48 horas.

BigQuery Editions e autoscaler de slots

Editions introduziram um recurso transformador para FinOps: o autoscaler de slots. Você define um baseline (slots sempre disponíveis) e um máximo (limite de expansão automática). O BigQuery escala em incrementos de 100 slots baseado na fila de queries em tempo real. Se ninguém está usando o warehouse, você paga apenas pelo baseline. Se um analista dispara uma query pesada, os slots crescem em segundos.

-- Criar uma reservation com autoscaling via bq CLI
bq mk --project_id=meu-projeto \
  --reservation \
  --location=us \
  --slots=500 \
  --autoscale_max_slots=2000 \
  --edition=ENTERPRISE \
  analytics_reservation

# Atribuir workloads de produção à reservation
bq mk --project_id=meu-projeto \
  --reservation_assignment \
  --reservation_id=analytics_reservation \
  --assignee_type=PROJECT \
  --assignee_id=meu-projeto-prod \
  --job_type=QUERY

O padrão recomendado para 2026: baseline pequeno com commitment de 1 ano (aproveita o desconto de 20%), autoscaler generoso (2x a 4x o baseline) sem commitment, e uma segunda reservation "sandbox" com slots=0 e autoscale_max_slots baixo para projetos experimentais. Você impede que um analista curioso consuma slots reservados para produção enquanto ainda oferece capacidade sob demanda.

Combinar essa estratégia com um modelo de maturidade FinOps maduro (com showback por equipe, alertas automáticos e revisão trimestral de commitments) é o que separa organizações que gastam previsivelmente daquelas que se surpreendem com faturas de US$ 100.000 no final do mês. Já vi ambos os cenários. A diferença raramente é técnica, quase sempre é processo.

Erros comuns que inflam a conta do BigQuery

Depois de auditar dezenas de projetos, os mesmos padrões de desperdício aparecem repetidamente. Estes são os cinco mais caros que encontrei em 2026:

  1. Streaming inserts em vez de batch loads: US$ 0,01 por 200 MB via tabledata.insertAll. Uma pipeline que ingere 500 GB/dia paga US$ 750/mês apenas em streaming, quando batch loads (gratuitos) resolveriam.
  2. Tabelas sem particionamento: qualquer tabela >10 GB que recebe queries diárias deveria estar particionada. A migração paga em dias.
  3. Dashboards atualizando a cada minuto: refresh rate de 1 minuto em Looker sem BI Engine consome slots freneticamente. Aumente para 15 a 30 minutos ou use materialized views.
  4. Datasets órfãos: datasets criados para experimentos que nunca foram deletados acumulam TB de long-term storage. Use uma estratégia de tags para alocação de custos para identificar recursos sem dono.
  5. Nested queries com WITH mal escritas: uma CTE referenciada 3 vezes é executada 3 vezes. Materialize resultados intermediários em tabelas temporárias quando reutilizados.

Adotar essas práticas de forma sistemática, apoiadas por dashboards de INFORMATION_SCHEMA e alertas de anomalia, transforma o BigQuery de uma "caixa preta cara" em um dos data warehouses com melhor custo-benefício do mercado. A infraestrutura escala, mas a fatura também precisa escalar com controle.

Perguntas frequentes

Quanto custa o BigQuery em 2026?

No modelo on-demand, o BigQuery cobra US$ 6,25 por TB processado (o primeiro TB por mês é gratuito). Armazenamento custa US$ 0,02/GB para dados ativos e US$ 0,01/GB para long-term (após 90 dias sem edição). Slot reservations via Editions começam em US$ 0,04/slot-hora (Standard) e chegam a US$ 0,10/slot-hora (Enterprise Plus), com descontos de 20% a 40% para commitment de 1 ou 3 anos.

Qual a diferença entre particionamento e clustering no BigQuery?

Particionamento divide fisicamente a tabela em blocos separados (por data, por range de inteiro ou por coluna de ingestão), permitindo que o BigQuery pule blocos irrelevantes. Clustering ordena os dados dentro de cada bloco, otimizando filtros e joins em colunas de alta cardinalidade. Os dois são complementares: particione por data, agrupe por user_id ou region.

Quando devo migrar de on-demand para BigQuery Editions?

A regra prática é migrar quando você processa mais de 400 TB/mês de forma previsível. Use o Slot Recommender do Google Cloud para uma análise baseada nos seus últimos 30 dias de uso. Um padrão híbrido, com Editions e autoscaler para produção e on-demand para experimentação, costuma ser o mais custo-efetivo em organizações médias.

Materialized views substituem tabelas agregadas manuais?

Sim, na maioria dos casos. Materialized views são mantidas incrementalmente pelo BigQuery, roteadas automaticamente pelo otimizador de queries e não exigem manutenção de pipelines de ETL. Elas têm limites (algumas funções não são suportadas), mas para agregações padrão de dashboards oferecem economia dramática sem overhead operacional.

Como limitar o custo máximo de uma query no BigQuery?

Use o parâmetro maximum_bytes_billed. Ele pode ser definido por query, por usuário via Cloud Resource Manager, ou por projeto. Se a query estimar mais bytes que o limite, o BigQuery aborta antes de executar. Combine com --dry_run no CI/CD para validar novas queries antes de mergear.

Sobre o Autor Editorial Team

Our team of expert writers and editors.