O licenciamento Microsoft Fabric opera em um modelo baseado em capacidade onde organizações compram unidades de compute (CUs) compartilhadas entre todos os workloads — Power BI, Data Factory, Synapse e mais. A estrutura de billing cria um desafio persistente de otimização: superdimensione e você queima orçamento; subdimensione e relatórios dão timeout nos horários de pico.
A maioria das organizações opta por superdimensionar porque a alternativa — executivos irritados encarando ícones de loading girando — é politicamente inaceitável. Mas superdimensionar em tier F64 ou P2 quando F32 ou P1 seria suficiente desperdiça dezenas de milhares de dólares anualmente.
Este artigo apresenta o framework de auditoria sistemática que aplicamos na Montinegro Corp para right-sizing de capacidade Fabric, eliminação de desperdício e redução de gastos de 30-50% sem degradar a experiência do usuário final.
Entendendo a Estrutura de Custos
Antes de otimizar, você precisa entender pelo que está pagando. O pricing de capacidade Fabric segue um modelo em tiers:
| SKU | CU/s por janela de 30s | Custo Mensal Aproximado (USD) | Custo Mensal Aprox. (BRL) |
|---|---|---|---|
| F2 | 2 | ~$260 | ~R$1.450 |
| F4 | 4 | ~$520 | ~R$2.900 |
| F8 | 8 | ~$1.040 | ~R$5.800 |
| F16 | 16 | ~$2.080 | ~R$11.600 |
| F32 | 32 | ~$4.160 | ~R$23.200 |
| F64 | 64 | ~$8.320 | ~R$46.400 |
| F128 | 128 | ~$16.640 | ~R$92.800 |
O detalhe crítico que a maioria das organizações ignora: capacidade é cobrada continuamente, não por uso. Uma F64 rodando a 5% de utilização às 3h da manhã custa o mesmo que uma F64 rodando a 95% de utilização às 9h.
Fase 1: Auditoria de Utilização de Capacidade
O primeiro passo é medir a utilização real. A Microsoft fornece o app Fabric Capacity Metrics, mas suas views padrão agregam dados de formas que obscurecem as oportunidades de otimização.
Rodamos auditorias programáticas usando a API REST do Power BI e queries DMV (Dynamic Management Views) através do nosso catálogo de scripts admin:
Consumo de CU por Workspace
# Padrão simplificado de extração
import requests
def get_workspace_consumption(access_token, capacity_id, days=30):
"""Extrair consumo de CU por workspace em um período."""
headers = {'Authorization': f'Bearer {access_token}'}
url = f'https://api.powerbi.com/v1.0/myorg/admin/capacities/{capacity_id}/workloads'
response = requests.get(url, headers=headers)
workloads = response.json()['value']
# Cross-reference com eventos de atividade de workspace
activity_url = 'https://api.powerbi.com/v1.0/myorg/admin/activityevents'
# ... agregar por workspace, computar atribuição de CU
O output revela quais workspaces estão consumindo capacidade desproporcional. Em toda auditoria que conduzimos, a distribuição segue um padrão consistente:
- Top 5% dos workspaces consomem 60-70% do CU total
- Bottom 50% dos workspaces consomem menos de 5% do CU total
- 10-20% dos workspaces estão completamente inativos (sem refreshes, sem queries em 30+ dias)
O Problema dos Workspaces Zumbi
Workspaces inativos não consomem CU diretamente, mas ocupam overhead organizacional: atenção de admin, superfície de segurança e confusão sobre o que está ativo. Mais criticamente, workspaces inativos frequentemente contêm datasets com refreshes agendados que ninguém consome.
Encontramos clientes rodando 40+ refreshes diários de datasets que alimentam relatórios que ninguém abriu em meses. Cada refresh consome CU para zero valor de negócio.
Remediação: Consulte a API de eventos de atividade por eventos ViewReport por workspace nos últimos 90 dias. Qualquer workspace com zero eventos de view é candidato a arquivamento ou deleção.
Fase 2: Otimização de Schedule de Refresh
Refreshes de datasets são o maior consumidor de CU na maioria dos deployments Power BI. Uma estratégia de refresh mal planejada pode consumir 3-5x mais capacidade que o necessário.
O Problema: Refreshes Sincronizados
Muitas organizações agendam todos os refreshes no mesmo horário — tipicamente 6h ou meia-noite. Isso cria um pico massivo de CU que ou:
- Excede os limites de capacidade, causando throttling e refreshes falhados
- Força a organização a comprar capacidade de tier mais alto para lidar com o pico de 30 minutos
As 23.5 horas restantes do dia, a capacidade fica subutilizada.
A Solução: Janelas de Refresh Escalonadas
Calculamos schedules ótimos de refresh baseados em três fatores:
- Criticidade de negócio: Dashboards executivos fazem refresh primeiro
- Requisitos de freshness de dados: Relatórios operacionais real-time vs relatórios estratégicos semanais
- Tamanho do dataset: Datasets maiores ganham janelas de tempo isoladas para evitar contenção de CU
Exemplo de Schedule Otimizado:
────────────────────────────────────────
00:00 - 01:00 │ Tier 1: Dashboards executivos (3 datasets)
01:00 - 02:00 │ Tier 2: Relatórios de operações (8 datasets)
02:00 - 04:00 │ Tier 3: Modelos analíticos (15 datasets)
04:00 - 05:00 │ Tier 4: Workspaces de desenvolvimento (5 datasets)
06:00 - 06:30 │ Tier 1: Refresh matinal para dados de abertura de mercado
12:00 - 12:30 │ Tier 1: Refresh do meio-dia
────────────────────────────────────────
Pico de CU draw: ~45% (era 95%+ com schedule sincronizado)
Configuração de Refresh Incremental
Para datasets grandes (>10M linhas), refreshes full são desperdiciativos. Políticas de refresh incremental particionam o dataset por data e fazem refresh apenas da partição mais recente:
Full Refresh: 50M linhas × 4 min = 200 CU-segundos
Incremental: 2M linhas × 0.3 min = 6 CU-segundos
Economia: 97% por ciclo de refresh
A configuração requer particionamento por data adequado no data model e parâmetros RangeStart/RangeEnd no Power Query. Auditamos cada dataset acima de 5M linhas para elegibilidade de refresh incremental.
Fase 3: Otimização de Performance de Queries
Queries lentas consomem CU proporcionalmente ao tempo de execução. Um relatório que leva 15 segundos para renderizar consome 15x mais CU que um relatório que renderiza em 1 segundo.
Profiling de Queries DAX
Usamos queries DMV para identificar as operações DAX mais caras:
SELECT
[OBJECT_ID],
[OBJECT_CPU_TIME_MS],
[OBJECT_READS],
[OBJECT_READ_KB],
[OBJECT_USED_MEMORY]
FROM $SYSTEM.DISCOVER_OBJECT_ACTIVITY
ORDER BY [OBJECT_CPU_TIME_MS] DESC
As top 10 queries mais caras tipicamente respondem por 40-60% do consumo total de CU de queries. Otimizar essas queries sozinhas pode reduzir requisitos de capacidade em 15-25%.
Anti-Patterns DAX Comuns
1. CALCULATE com transição de contexto desnecessária
// Caro: Força full table scan
Medida Ruim =
CALCULATE(
SUM(Vendas[Valor]),
ALL(Vendas)
)
// Otimizado: Usa SUMX apenas quando contexto de linha é necessário
Medida Boa =
SUMX(
VALUES(Produtos[Categoria]),
[Vendas por Categoria]
)
2. Funções iteradoras em tabelas grandes
// Caro: SUMX itera linha por linha em milhões
Revenue Ruim =
SUMX(
Vendas,
Vendas[Quantidade] * RELATED(Produtos[Preco])
)
// Otimizado: Pré-calcule no Power Query ou use medida
Revenue Bom =
SUM(Vendas[Revenue]) -- Coluna computada no refresh
3. Uso excessivo de DISTINCTCOUNT
DISTINCTCOUNT é uma das operações DAX mais caras porque requer escanear e deduplicar a coluna inteira. Para colunas de alta cardinalidade (>1M valores distintos), considere:
- Pré-agregar no Power Query
- Usar distinct count aproximado se precisão não é crítica
- Particionar o cálculo por ranges de data
Fase 4: Right-Sizing de Capacidade
Após otimizar refreshes e queries, o perfil real de consumo de CU fica claro. Então fazemos right-sizing:
A Matriz de Decisão
| Pico Atual de CU | Média Sustentada | Recomendação |
|---|---|---|
| >90% da capacidade | >60% média | Manter tier atual |
| >90% da capacidade | <40% média | Otimizar scheduling, reavaliar |
| <60% da capacidade | <30% média | Downgrade um tier |
| <40% da capacidade | <20% média | Downgrade dois tiers |
Configuração de Auto-Scale
Para organizações com padrões de uso previsíveis (alto durante horário comercial, mínimo overnight), Fabric suporta auto-scaling de capacidade. Configuramos:
- Capacidade base: F16 (lida com refreshes overnight e períodos de baixo tráfego)
- Trigger de scale-up: 75% CU sustentado por 10 minutos
- Target de scale-up: F32 (lida com carga de queries em horário comercial)
- Trigger de scale-down: <30% CU sustentado por 30 minutos
- Target de scale-down: Retorno para F16
Esse padrão reduz o custo mensal efetivo em 30-40% comparado a uma alocação estática F32.
Fase 5: Automação de Governança
Otimização não é um evento único. Sem governança contínua, organizações deslizam de volta à ineficiência em 3-6 meses conforme novos workspaces são criados, novos datasets são publicados e novos schedules de refresh são configurados.
Implantamos governança automatizada através de pipelines CI/CD que:
- Bloqueiam datasets oversized de publicação em produção (>500MB sem refresh incremental configurado)
- Alertam sobre falhas de refresh que excedem 3 ocorrências consecutivas
- Reportam semanalmente tendências de utilização de capacidade com detecção de anomalia
- Marcam workspaces inativos trimestralmente para revisão
O Framework de ROI
Para uma organização de médio porte rodando capacidade F64:
| Otimização | Redução de CU | Economia Mensal (USD) | Economia Mensal (BRL) |
|---|---|---|---|
| Limpeza de workspaces zumbi | 5-10% | $400-$830 | R$2.230-R$4.630 |
| Escalonamento de schedule de refresh | 15-25% | $1.250-$2.080 | R$6.980-R$11.600 |
| Adoção de refresh incremental | 10-20% | $830-$1.660 | R$4.630-R$9.260 |
| Otimização de queries DAX | 10-15% | $830-$1.250 | R$4.630-R$6.980 |
| Right-sizing de capacidade (F64→F32) | 50% | $4.160 | R$23.200 |
| Economia potencial total | $7.470-$9.980/mês | R$41.670-R$55.670/mês |
Anualizado, são $89.640-$119.760 (R$500.000-R$668.000) em custos reduzidos de licenciamento Fabric. O engagement de auditoria e otimização tipicamente custa uma fração da economia do primeiro ano.
O Bottom Line
Otimização de capacidade Fabric não é sobre cortar gastos. É sobre garantir que cada CU consumida entregue valor de negócio. As organizações que tratam gestão de capacidade como uma disciplina de engenharia — não como reflexão tardia — consistentemente gastam 30-50% menos enquanto entregam reporting mais rápido e confiável para seus stakeholders.