MÓDULO 08 · CONCEITO 02 DE 14

Error Budgets

Velocidade e confiabilidade no mesmo número — o instrumento que transforma o conflito em parceria

Tempo de leitura ~22 min Pré-requisito 01 · SLI, SLO e SLA Próximo 03 · Bulkhead e isolation patterns

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%
heurística do sênior

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).
armadilha de adoção

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 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.

C# — Burn rate calculator com janelas múltiplas
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.

Python — Burn rate com alertas
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]).

Go — Burn rate com alertas Prometheus
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?"

princípio orientador

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

  1. 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.
  2. 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.
  3. 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

  1. livro Site Reliability Engineering — Beyer et al. (O'Reilly, 2016). Capítulo 3 ("Embracing Risk") e capítulo 5 ("Eliminating Toil") são as fontes primárias do conceito de error budget como ferramenta de alinhamento.
  2. livro The Site Reliability Workbook — Fowler et al. (O'Reilly, 2018). Capítulo 2 trata de SLOs e error budgets em profundidade prática. O esquema de alertas de burn rate (14.4×/1×) vem deste capítulo.
  3. artigo Error Budget Policy — How to Write One — Liz Fong-Jones (Honeycomb, 2021). Guia prático de como escrever e negociar uma política de error budget em organizações reais. Inclui exemplos de políticas para times de diferentes tamanhos.
  4. vídeo Error Budgets and the Art of SLOs — Google Cloud Next '19. YouTube. Apresentação de 45 minutos sobre error budgets em prática — como o Google usa internamente e como adaptar para times menores.
  5. artigo The Error Budget in Practice — David Rensin (Google, 2020). Artigo do criador do programa de SRE clientes do Google sobre como o conceito funciona (e falha) em organizações fora do Google.
  6. docs Prometheus Alerting Rules — SLO Examples — Prometheus.io. prometheus.io/docs/practices/alerting. Exemplos de regras de alerta para burn rate em YAML do Prometheus.
  7. artigo SLO Burn Rate Alerts — Google Cloud Monitoring docs. cloud.google.com/monitoring/slo-monitoring. Tutorial passo a passo de configuração de alertas de burn rate no Google Cloud Monitoring.
  8. livro Implementing Service Level Objectives — Alex Hidalgo (O'Reilly, 2020). Capítulos 7-9 cobrem error budgets em detalhe — política, cálculo, comunicação com stakeholders. O livro mais prático sobre o tema.
  9. artigo How We Used Error Budgets to Improve Developer Confidence — Atlassian Engineering, 2022. Caso real de adoção de error budgets fora do Google, com aprendizados sobre o que funcionou e o que precisou de adaptação.
  10. paper Managing the Risk of Cascading Failure — USENIX SREcon 2019. Relaciona consumo de error budget com risco de falha em cascata — como budget baixo correla com sistemas em "modo frágil".
  11. vídeo SLOs, Error Budgets, and You — Charity Majors (Strange Loop, 2021). YouTube. Palestra honesta sobre a dificuldade real de adotar SLOs e error budgets em organizações com cultura de ops tradicional.
  12. docs OpenSLO Specification — OpenSLO.com. Especificação aberta para definir SLOs em YAML agnóstico de provedor. Facilita portabilidade de SLOs entre Datadog, Grafana, Google Cloud.