A tensão entre time de produto e time de engenharia é uma das mais antigas da indústria: produto quer velocidade de entrega, engenharia quer estabilidade do sistema. Sem um mecanismo de mediação objetivo, a decisão de "podemos fazer esse deploy hoje?" vira uma negociação política — quem grita mais alto, quem tem mais senioridade, quem tem mais medo de incidente. O error budget foi projetado para resolver exatamente isso: substituir a negociação subjetiva por um número compartilhado.
Ben Treynor Sloss, fundador do SRE do Google, articulou o conceito pela primeira vez em documentos internos do Google nos anos 2000. A ideia central é simples e poderosa: se o SLO é 99.9% de disponibilidade em 30 dias, então 0.1% de indisponibilidade é aceita — é o erro que o sistema pode cometer sem violar o que prometeu ao usuário. Esse 0.1% é o error budget. Ele não é desperdício: é um ativo que o time pode gastar em atividades de alto risco.
A transformação organizacional que o error budget opera é esta: quando o budget está cheio, o time tem espaço para arriscar — deploys frequentes, experimentos de chaos, refatorações agressivas, feature flags ligados para novos usuários. Quando o budget está esgotado, o sinal é claro: o sistema está custando mais confiabilidade do que prometemos, e a prioridade passa a ser estabilização, não velocidade. Não é punição — é informação.
Este conceito explora a mecânica do error budget em detalhe: como derivá-lo do SLO, como medir seu consumo em tempo real, como definir a política de budget (o que acontece quando esgota), e como os alertas de burn rate funcionam como sistema de alerta antecipado antes do esgotamento.
A matemática do error budget
O error budget é derivado diretamente do SLO. A fórmula é:
error_budget = (1 - SLO_target) × janela
Exemplos:
SLO 99.9% em 30 dias →
budget = 0.001 × 30 × 24 × 60 = 43.2 minutos
SLO 99.95% em 30 dias →
budget = 0.0005 × 30 × 24 × 60 = 21.6 minutos
SLO 99% em 30 dias →
budget = 0.01 × 30 × 24 × 60 = 432 minutos (7.2h)
Mas "minutos de downtime" é uma simplificação. Em sistemas reais, o budget é medido em requisições ruins, não em tempo. Se o sistema processa 10 milhões de requisições por mês e o SLO é 99.9%, o error budget é 10.000 requisições que podem falhar. Isso é mais útil operacionalmente porque não pressupõe que falhas acontecem como períodos contínuos de downtime total — normalmente são taxas elevadas de erro por janelas curtas.
Modelo de budget por requisições:
volume_mensal = 10.000.000 req/mês
SLO = 99.9%
error_budget = 10.000.000 × 0.001 = 10.000 requisições ruins
Se um incidente gera taxa de erro de 5% por 2 horas:
volume em 2h = 10M/720 × 2 ≈ 27.778 req
requisições ruins = 27.778 × 0.05 ≈ 1.389 req ruins
consumo do budget = 1.389 / 10.000 = 13.9%
Calcule o error budget tanto em tempo quanto em requisições, e use o que for mais intuitivo para o seu contexto. Para sistemas web com tráfego relativamente constante, ambos são equivalentes. Para sistemas com tráfego muito variável (pico em horário comercial, vale de madrugada), budget em requisições é mais preciso — um incidente de madrugada consome muito menos budget que o mesmo incidente às 14h.
Budget consumido vs budget restante
O estado do error budget tem três zonas relevantes:
Budget saudável (>50% restante): o time está dentro do esperado. Deploys normais, experimentos planejados de chaos, novas features — tudo é bem-vindo. Este é o regime de velocidade máxima.
Budget em atenção (10–50% restante): a situação não é crítica mas requer atenção. É hora de investigar o que está consumindo budget — são incidentes recorrentes? Deploys com problemas? Degradação de performance? O time não precisa parar, mas precisa investigar.
Budget esgotado (<10% restante ou zerado): o sistema está entregando menos do que prometeu. A política de error budget define o que acontece aqui — tipicamente, freeze de mudanças que não sejam diretamente orientadas a estabilização.
Política de error budget
A política é o documento que transforma o error budget de métrica em mecanismo de decisão. Sem política, o budget é um número que as pessoas olham mas não agem sobre ele. Com política, o número aciona comportamentos específicos de forma automática — sem reunião, sem negociação, sem aprovação de VP.
Uma política típica tem três elementos: o gatilho (qual threshold de budget aciona a política), a resposta (o que o time deve fazer), e a exceção (quem pode aprovar ação fora da política em casos extraordinários).
POLÍTICA DE ERROR BUDGET — Checkout Service
Gatilho 1: Budget entre 25% e 10% restante
Resposta: pausar deploys de feature nova;
priorizar investigação de causas de consumo;
comunicar status ao PO.
Exceção: tech lead pode aprovar deploy urgente de
hotfix de segurança.
Gatilho 2: Budget abaixo de 10% restante
Resposta: freeze total de mudanças não-estabilizadoras;
incidente declarado (nível P2);
daily sync com PO e Engenharia até recuperação.
Exceção: só CTO pode aprovar deploy em freeze total.
Gatilho 3: Budget esgotado (0% restante)
Resposta: postmortem obrigatório;
revisar arquitetura de disponibilidade;
considerar revisão do SLO para próximo período.
Resetar: budget se renova na virada do período (30 dias).
Política de error budget sem comprometimento da liderança é decoração. Se o VP de Produto pode simplesmente ignorar o freeze e aprovar deploys de feature quando quer, a política não funciona. O erro mais comum na adoção de SRE em empresas fora do Google é adotar o vocabulário (SLO, error budget, burn rate) sem adotar a mudança cultural necessária: produto e engenharia de fato compartilham o número e de fato respeitam a política.
Burn rate — a velocidade de consumo
Burn rate mede com que velocidade o error budget está sendo consumido em relação à taxa "sustentável". Burn rate de 1× significa que o budget está sendo consumido exatamente na taxa que o esgotaria no fim do período se continuasse nesse ritmo — isso é neutro, dentro do esperado. Burn rate de 2× significa que o budget seria esgotado em metade do período.
A fórmula é:
burn_rate = taxa_de_erro_observada / taxa_de_erro_alvo
taxa_de_erro_alvo = 1 - SLO_target
Exemplos:
SLO = 99.9% → taxa_de_erro_alvo = 0.001 (0.1%)
Observando taxa de erro de 0.5%:
burn_rate = 0.005 / 0.001 = 5×
Observando taxa de erro de 0.05%:
burn_rate = 0.0005 / 0.001 = 0.5× (ótimo, abaixo do sustentável)
O burn rate é mais útil que o "budget consumido até agora" porque é um indicador antecipado — ele mostra o que vai acontecer se nada mudar, não apenas o que já aconteceu. Um burn rate de 10× hoje, mesmo que o budget ainda esteja a 80%, significa que em 3 dias o budget estará esgotado. Isso permite ação preventiva.
Alertas de burn rate — o esquema do Google
O Google SRE Workbook (2018) formalizou um esquema de dois alertas complementares que cobre tanto emergências quanto degradação lenta. A lógica é que um único alerta não consegue cobrir ambos os cenários eficientemente: um alerta sensível o suficiente para pegar degradações lentas dispara frequentemente em falsos positivos; um alerta robusto o suficiente para ignorar ruído pode não detectar consumo gradual de budget.
| Alerta | Burn rate mínimo | Janela de observação | Tempo para esgotar budget | Urgência |
|---|---|---|---|---|
| Fast burn | 14.4× | 1 hora | ~2 dias | Imediata — incidente |
| Slow burn | 1× | 72 horas (3 dias) | 30 dias | Alta — investigar hoje |
O número 14.4× no fast burn não é arbitrário: 30 dias / 2 dias = 15, menos uma tolerância = ~14.4. Se o sistema está queimando budget a 14.4×, em 2 dias o budget mensal inteiro terá sido consumido. Isso é sempre um incidente que precisa de atenção imediata.
O slow burn de 1× por 72 horas detecta situações onde o sistema está constantemente no limite — nunca queimando rápido o suficiente para disparar o fast burn, mas acumulando consumo gradual que eventualmente esgota o budget. Exemplos típicos: dependências externas com degradação de qualidade, aumento de latência P99 que não chega a ser timeout, deployment que aumentou levemente a taxa de erro.
public class BurnRateMonitor
{
private readonly SloTracker _tracker;
private readonly double _sloTarget;
public record BurnRateStatus(
double Rate1h,
double Rate6h,
double Rate72h,
bool FastBurnAlert,
bool SlowBurnAlert
);
public BurnRateMonitor(SloTracker tracker, double sloTarget)
{
_tracker = tracker;
_sloTarget = sloTarget;
}
private double ComputeBurnRate(TimeSpan window)
{
var (sli, _) = _tracker.GetForWindow(window);
if (sli >= 1.0) return 0;
double errorRate = 1 - sli;
double targetErrorRate = 1 - _sloTarget;
return errorRate / targetErrorRate;
}
public BurnRateStatus Evaluate()
{
var rate1h = ComputeBurnRate(TimeSpan.FromHours(1));
var rate6h = ComputeBurnRate(TimeSpan.FromHours(6));
var rate72h = ComputeBurnRate(TimeSpan.FromHours(72));
// fast burn: >14.4x em janela de 1h OU 6h
bool fastBurn = rate1h > 14.4 || rate6h > 14.4;
// slow burn: >1x sustentado por 72h
bool slowBurn = rate72h > 1.0;
return new BurnRateStatus(rate1h, rate6h, rate72h,
fastBurn, slowBurn);
}
}
Em produção, use Prometheus com rate() e increase() em vez de tracking in-process. O padrão acima é útil para testes e ambientes sem Prometheus.
from dataclasses import dataclass
from datetime import timedelta
@dataclass
class BurnRateStatus:
rate_1h: float
rate_6h: float
rate_72h: float
fast_burn_alert: bool
slow_burn_alert: bool
@property
def summary(self) -> str:
if self.fast_burn_alert:
return f"FAST BURN {self.rate_1h:.1f}x — ação imediata"
if self.slow_burn_alert:
return f"SLOW BURN {self.rate_72h:.1f}x — investigar hoje"
return f"OK {self.rate_1h:.2f}x"
class BurnRateMonitor:
def __init__(self, tracker: SloTracker, slo_target: float):
self.tracker = tracker
self.error_budget_rate = 1 - slo_target
def _burn_rate(self, window: timedelta) -> float:
sli = self.tracker.sli_for_window(window)
if sli >= 1.0:
return 0.0
error_rate = 1 - sli
return error_rate / self.error_budget_rate
def evaluate(self) -> BurnRateStatus:
r1h = self._burn_rate(timedelta(hours=1))
r6h = self._burn_rate(timedelta(hours=6))
r72h = self._burn_rate(timedelta(hours=72))
fast = r1h > 14.4 or r6h > 14.4
slow = r72h > 1.0
return BurnRateStatus(r1h, r6h, r72h, fast, slow)
Substitua SloTracker.sli_for_window por uma query Prometheus via API quando em produção: 1 - rate(http_requests_total{status=~"5.."}[1h]) / rate(http_requests_total[1h]).
type BurnRateStatus struct {
Rate1h float64
Rate6h float64
Rate72h float64
FastBurnAlert bool
SlowBurnAlert bool
}
func (s BurnRateStatus) String() string {
if s.FastBurnAlert {
return fmt.Sprintf("FAST BURN %.1fx — ação imediata", s.Rate1h)
}
if s.SlowBurnAlert {
return fmt.Sprintf("SLOW BURN %.1fx — investigar hoje", s.Rate72h)
}
return fmt.Sprintf("OK %.2fx", s.Rate1h)
}
func burnRate(errorRate, targetErrorRate float64) float64 {
if targetErrorRate == 0 { return 0 }
return errorRate / targetErrorRate
}
func EvaluateBurnRate(
sli1h, sli6h, sli72h float64,
sloTarget float64,
) BurnRateStatus {
target := 1 - sloTarget
r1h := burnRate(1-sli1h, target)
r6h := burnRate(1-sli6h, target)
r72h := burnRate(1-sli72h, target)
return BurnRateStatus{
Rate1h: r1h,
Rate6h: r6h,
Rate72h: r72h,
FastBurnAlert: r1h > 14.4 || r6h > 14.4,
SlowBurnAlert: r72h > 1.0,
}
}
// Em produção, SLIs vêm de queries Prometheus via API HTTP
O padrão real é configurar alertas no próprio Prometheus/Alertmanager com regras YAML — não polling em Go. O código acima é útil para dashboards custom e decisões programáticas.
Error budget como conversa organizacional
O valor mais profundo do error budget não é técnico — é organizacional. Sem ele, a conversa entre produto e engenharia sobre disponibilidade oscila entre dois extremos disfuncionais: ou engenharia diz "não podemos fazer esse deploy, vai quebrar" (sem dado objetivo), ou produto diz "é urgente, tem que ir hoje" (sem dado objetivo). Com o error budget, a conversa muda de "quem tem medo de quê" para "quanto budget temos e quanto esse deploy provavelmente custa".
Um time maduro usa o error budget como moeda de troca explícita. "Temos 60% do budget intacto. Esse deploy de feature nova tem risco estimado de 5% do budget com base no histórico de deploys similares — podemos fazer." Ou: "Temos 15% do budget e faltam 10 dias no mês. Mesmo um deploy sem incidente pode nos colocar em freeze. Vamos esperar o reset do período ou melhorar a confiabilidade primeiro?"
Error budget não é instrumento de punição de quem causar incidente. É instrumento de alinhamento de prioridades. Times que usam o budget para apontar culpa ("você causou um incidente que gastou 30% do budget") destroem a cultura de segurança psicológica que o blameless postmortem requer. O budget é informação sobre o sistema, não julgamento sobre pessoas.
Error budget em times que não são Google
Um equívoco comum é achar que error budget só funciona em escala do Google. Na verdade, a mecânica escala para baixo com facilidade — o que muda é a sofisticação da implementação. Um time de 5 engenheiros pode implementar um error budget completamente válido com uma planilha, um dashboard Grafana, e um documento de política de 1 página.
O que não escala bem é a formalidade excessiva: postmortem obrigatório de 20 páginas para todo incidente, reuniões semanais de review de error budget com 15 pessoas, alertas de burn rate configurados em Prometheus Enterprise antes de ter qualquer dado histórico. Começar simples — um SLO, um budget calculado manualmente por semana, uma política de freeze informal — e evoluir conforme o time amadurece é o caminho certo.
O efeito do reset periódico
Uma característica do error budget que gera debates é o reset periódico. Se o budget é mensal e esgotou no dia 20, o time fica em freeze até o dia 30 — e então na meia-noite do dia 1 o budget reseta e tudo está liberado novamente. Isso pode parecer artificial: o sistema não "ficou mais confiável" por causa do calendário.
O Google SRE Book defende o reset porque ele garante que cada período tem uma análise independente — um mês ruim não penaliza o próximo mês por meses. Mas há nuances: se um sistema esgota o budget 3 meses consecutivos, o reset não resolve o problema estrutural — ele apenas fecha os olhos para ele. Times maduros usam a recorrência de budget esgotado como sinal para revisão do SLO (talvez seja muito agressivo) ou revisão arquitetural (talvez o sistema não suporte o SLO atual sem mudanças).
Budget e chaos engineering
Há uma relação elegante entre error budget e chaos engineering que o Google SRE Book articula: experimentos de chaos também consomem error budget. Quando você injeta latência ou erros em produção como experimento controlado, você está intencionalmente degradando o SLI — e isso conta como consumo de budget.
Isso cria um incentivo poderoso para fazer chaos com eficiência. Um time que tem 40% de budget restante pode alocar deliberadamente 10% para um experimento de chaos de alto valor — um game day que testa failover de banco de dados, por exemplo. O gasto intencional de budget em chaos é diferente do gasto involuntário em incidentes: o primeiro gera aprendizado, o segundo gera postmortem.
A decisão de quanto budget gastar em chaos versus preservar para "margem de segurança" é uma das mais interessantes que o framework error budget permite — e é uma conversa que, sem o número compartilhado, nem aconteceria.
Como praticar
- Simular o consumo de budget histórico. Usando o serviço do exercício do conceito anterior (com SLIs instrumentados), calcule retroativamente qual teria sido o consumo de error budget nos últimos 30 ou 60 dias. Em quais dias o burn rate teria disparado alertas? Qual teria sido o estado do budget ao fim de cada semana? Isso calibra sua intuição sobre o que "budget saudável" parece na prática.
- Redigir uma política de budget de 1 página. Para o mesmo serviço, escreva uma política de error budget com três gatilhos (atenção, freeze, esgotado), a resposta esperada para cada um, e a exceção que permite sobrescrever a política. Mostre para o time de produto e engenharia. O debate que surgir é mais valioso que o documento final.
- Configurar alertas de burn rate. Com Prometheus e Grafana (ou equivalente), configure as duas regras de alerta: fast burn (14.4× por 1 hora) e slow burn (1× por 72 horas). Observe por 2 semanas sem tomar ação — apenas calibrar o threshold. Depois ative as notificações reais.
Referências para aprofundar
- livro Site Reliability Engineering — Beyer et al. (O'Reilly, 2016).
- livro The Site Reliability Workbook — Fowler et al. (O'Reilly, 2018).
- artigo Error Budget Policy — How to Write One — Liz Fong-Jones (Honeycomb, 2021).
- vídeo Error Budgets and the Art of SLOs — Google Cloud Next '19.
- artigo The Error Budget in Practice — David Rensin (Google, 2020).
- docs Prometheus Alerting Rules — SLO Examples — Prometheus.io.
- artigo SLO Burn Rate Alerts — Google Cloud Monitoring docs.
- livro Implementing Service Level Objectives — Alex Hidalgo (O'Reilly, 2020).
- artigo How We Used Error Budgets to Improve Developer Confidence — Atlassian Engineering, 2022.
- paper Managing the Risk of Cascading Failure — USENIX SREcon 2019.
- vídeo SLOs, Error Budgets, and You — Charity Majors (Strange Loop, 2021).
- docs OpenSLO Specification — OpenSLO.com.