SLOs e Error Budgets: da definição ao burn rate alert
- ⬜📉 Métricas RED e USE: os frameworks que cobrem 90% dos casos(Observabilidade & SRE)
Recomendamos completar os pré-requisitos antes de seguir, mas nada te impede de continuar.
Confiabilidade não é "servidor no ar". É ter uma definição clara e mensurável do que significa o sistema funcionar bem para o usuário — e honrá-la. SLOs (Service Level Objectives) são essa definição. Error budgets são o que transforma confiabilidade numa ferramenta de decisão de negócio.
A ideia central do SRE (Site Reliability Engineering) do Google: se você nunca está abaixo do SLO, você está sendo conservador demais — poderia lançar features mais rápido. Se está constantemente violando, você tem um problema de confiabilidade. O error budget é o saldo entre esses extremos. Neste módulo você vai do conceito à implementação real de alertas inteligentes.
SLI → SLO → SLA: a hierarquia
┌─────────────────────────────────────────────────────────────────┐
│ SLI — Service Level Indicator │
│ "O que eu meço" │
│ │
│ Ex: proportion of requests where latency < 300ms │
│ = successful_requests / total_requests │
└────────────────────┬────────────────────────────────────────────┘
│ define alvo para
┌────────────────────▼────────────────────────────────────────────┐
│ SLO — Service Level Objective │
│ "O alvo interno de confiabilidade" │
│ │
│ Ex: SLI ≥ 99.5% medido em janela rolling de 30 dias │
│ (= máx 0.5% de requests lentas ou com erro) │
└────────────────────┬────────────────────────────────────────────┘
│ base para (sempre mais frouxo)
┌────────────────────▼────────────────────────────────────────────┐
│ SLA — Service Level Agreement │
│ "O contrato com penalidades" │
│ │
│ Ex: ≥ 99.0% (folga de 0.5% em relação ao SLO) │
│ Se violar: crédito de 10% na fatura do cliente │
└─────────────────────────────────────────────────────────────────┘
Regra: SLA < SLO < 100%
Por quê: se o SLO = SLA, qualquer pequena falha interna gera
penalidade financeira sem buffer de aviso.
Como definir um bom SLI
SLI mede a experiência do usuário — não métricas de sistema. "CPU < 80%" não é um SLI. "% de requests completados em < 300ms" é.
| Tipo de SLI | Fórmula | Quando usar |
|---|---|---|
| Availability | successful_requests / total_requests | APIs, serviços HTTP — mede se o sistema está respondendo corretamente |
| Latency | requests_under_threshold / total_requests | UX-críticos — "% de buscas respondidas em < 200ms" |
| Throughput | requests_processed / target_rate | Pipelines de dados — "% de batches completados no tempo esperado" |
| Error rate | 1 - (error_requests / total_requests) | Alternativa a availability — foca em erros de aplicação, não infraestrutura |
| Quality | good_quality_responses / total_responses | Sistemas com degradação graciosa — recomendações com fallback ainda são "sucesso" |
# Definindo SLIs em Prometheus
# Métrica base: contador de requests por status
# Instrumentado pelo servidor HTTP automaticamente (ou manualmente):
from prometheus_client import Counter
REQUEST_COUNTER = Counter(
'http_requests_total',
'Total HTTP requests',
['method', 'handler', 'status_code']
)
# SLI de Availability: requests com 5xx são falhas
# PromQL:
availability_sli = """
sum(rate(http_requests_total{status_code!~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))
"""
# SLI de Latência: requests abaixo de 300ms (histograma)
from prometheus_client import Histogram
REQUEST_LATENCY = Histogram(
'http_request_duration_seconds',
'HTTP request duration',
['handler'],
buckets=[0.1, 0.3, 0.5, 1.0, 2.0, 5.0]
)
# PromQL para latency SLI:
latency_sli = """
sum(rate(http_request_duration_seconds_bucket{handler="/checkout",le="0.3"}[5m]))
/
sum(rate(http_request_duration_seconds_count{handler="/checkout"}[5m]))
"""Error budget: o saldo de falha permitido
Se o SLO é 99.5% em 30 dias, o error budget é os 0.5% restantes — convertido em tempo absoluto:
SLO = 99.5% → Error budget = 0.5% Janela de 30 dias = 43.200 minutos Error budget = 0.5% × 43.200 = 216 minutos = 3h36min ┌─────────────────────────────────────────────────────────┐ │ ERROR BUDGET TRACKER — Checkout Service — Jan 2024 │ │ │ │ Budget total: 216 min │ │ ████████████████████░░░░░░░░░░░░░░░░░░░░ 45% usado │ │ │ │ Consumido: 97 min │ │ • Incidente DB 03/Jan: 45 min │ │ • Deploy canário com bug 11/Jan: 32 min │ │ • Degradação CDN 18/Jan: 20 min │ │ │ │ Restante: 119 min (55%) │ │ Dias restantes no mês: 13 │ │ │ │ ✅ Budget disponível — time pode fazer releases │ └─────────────────────────────────────────────────────────┘ Se budget esgota antes do fim do mês: → Feature freeze: sem novos deploys de features → Time foca 100% em confiabilidade → Investigar o que está causando consumo anormal
Multi-window multi-burn rate alerts
O Google SRE Workbook definiu a estratégia de alertas mais eficaz para SLOs. A ideia: alertar quando a taxa de consumo do error budget é anormalmente alta — não só quando há erros.
Burn rate = taxa atual de consumo ÷ taxa normal esperada. Burn rate de 1 = consome o budget exatamente na janela. Burn rate de 2 = esgota o budget em metade do tempo.
SLO = 99.5% → error rate alvo = 0.5% Burn rate = current_error_rate / target_error_rate Ex: error rate atual = 5% → burn rate = 5% / 0.5% = 10× TABELA DE ALERTAS (Google SRE Workbook): ───────────────────────────────────────────────────────────────── Alerta │ Burn Rate │ Janela Curta │ Janela Longa │ Severidade ─────────┼───────────┼──────────────┼──────────────┼─────────── P1 │ 14.4× │ 1h │ 5min │ PagerDuty P2 │ 6× │ 6h │ 30min │ Slack urgente P3 │ 3× │ 3 dias │ 6h │ Ticket/email P4 │ 1× │ 30 dias │ - │ Weekly review ───────────────────────────────────────────────────────────────── P1 (14.4×): burn rate de 14.4 esgota budget em 30d/14.4 = 2 dias → Requer resposta imediata (pager) P3 (3×): burn rate de 3 esgota budget em 10 dias → Degradação silenciosa — ticket para investigar
# Prometheus alerting rules — multi-window multi-burn rate
# SLO: 99.5% availability no checkout em janela de 30 dias
groups:
- name: slo.checkout.availability
rules:
# SLI: proporção de requests bem-sucedidos
- record: job:slo_checkout_success_rate:ratio_rate5m
expr: |
sum(rate(http_requests_total{job="checkout",status!~"5.."}[5m]))
/
sum(rate(http_requests_total{job="checkout"}[5m]))
- record: job:slo_checkout_success_rate:ratio_rate1h
expr: |
sum(rate(http_requests_total{job="checkout",status!~"5.."}[1h]))
/
sum(rate(http_requests_total{job="checkout"}[1h]))
- record: job:slo_checkout_success_rate:ratio_rate6h
expr: |
sum(rate(http_requests_total{job="checkout",status!~"5.."}[6h]))
/
sum(rate(http_requests_total{job="checkout"}[6h]))
- record: job:slo_checkout_success_rate:ratio_rate3d
expr: |
sum(rate(http_requests_total{job="checkout",status!~"5.."}[3d]))
/
sum(rate(http_requests_total{job="checkout"}[3d]))
# P1: Burn rate 14.4× — incidente crítico
# Janela curta (5m) E janela longa (1h) devem satisfazer
# Reduz false positives de spikes breves
- alert: CheckoutSLOBurnRateCritical
expr: |
(
(1 - job:slo_checkout_success_rate:ratio_rate5m) > (14.4 * 0.005)
AND
(1 - job:slo_checkout_success_rate:ratio_rate1h) > (14.4 * 0.005)
)
for: 2m
labels:
severity: critical
team: checkout
annotations:
summary: "Checkout SLO: burn rate crítico (14.4×)"
description: |
Error rate atual: {{ $value | humanizePercentage }}
Budget consumido em: ~2 dias se continuar.
Runbook: https://wiki/checkout-slo-runbook
# P2: Burn rate 6× — degradação significativa
- alert: CheckoutSLOBurnRateHigh
expr: |
(
(1 - job:slo_checkout_success_rate:ratio_rate30m) > (6 * 0.005)
AND
(1 - job:slo_checkout_success_rate:ratio_rate6h) > (6 * 0.005)
)
for: 15m
labels:
severity: warning
team: checkout
annotations:
summary: "Checkout SLO: burn rate elevado (6×)"
# P3: Burn rate 3× — degradação lenta (só janela longa)
- alert: CheckoutSLOBurnRateSlow
expr: |
(1 - job:slo_checkout_success_rate:ratio_rate3d) > (3 * 0.005)
for: 1h
labels:
severity: warning
team: checkout
annotations:
summary: "Checkout SLO: degradação silenciosa nos últimos 3 dias"SLO vs uptime puro: por que 99.9% não é suficiente como alvo
"Uptime de 99.9%" (three-nines) parece ótimo mas disfarça problemas reais:
| Uptime | Downtime por mês | Downtime por ano | Adequado para |
|---|---|---|---|
| 99% | 7h 18min | 3d 15h | Sites internos, ferramentas não-críticas |
| 99.5% | 3h 39min | 1d 19h | APIs com baixa criticidade de negócio |
| 99.9% | 43 min | 8h 45min | APIs de produção consumer-grade |
| 99.95% | 21 min | 4h 22min | Plataformas B2B com SLA financeiro |
| 99.99% | 4 min | 52 min | Serviços de pagamento, infraestrutura crítica |
| 99.999% | 26 seg | 5 min | Telecoms, sistemas de segurança — requer arquitetura especial |
Toil budget: o outro lado do SRE
Toil (do inglês "lida") é o trabalho manual, repetitivo, tático que não tem valor de engenharia duradouro. A regra do SRE: máximo 50% do tempo de trabalho.
| É Toil | NÃO é Toil |
|---|---|
| Restart manual de serviço após crash | Criar runbook automatizado para o crash |
| Aprovar manualmente deploys um a um | Implementar pipeline de deploy automático com canary |
| Responder alertas de disco cheio ad hoc | Implementar auto-scaling ou limpeza automática de logs |
| Atualizar configurações em 20 servidores manualmente | Criar playbook Ansible/Terraform para a mudança |
| Resetar senha de usuário toda semana via ticket | Implementar self-service de reset de senha |
📋 Time de SRE gasta 70% do tempo respondendo alertas e fazendo tarefas manuais recorrentes
Com 70% em toil, o time não tem capacidade para automação. O ciclo vicioso: mais toil → menos automação → mais toil. Quebrar o ciclo requer alocar Sprint completo para eliminar as 3-5 maiores fontes de toil com automação (runbooks automatizados, auto-healing, alertas melhores).
Alt: Contratar mais SREs — Pode escalar a curto prazo mas não resolve o problema estrutural — mais SREs = mais toil sem automação
Alt: Delegar toil para times de dev — Distribui o problema mas não o elimina — desenvolvedores também têm tempo limitado
Alt: Aceitar o toil como custo — Anti-pattern absoluto — aumenta burnout e rotatividade de engenheiros de SRE
Error budget policy: o contrato entre produto e SRE
Uma política de error budget documenta o que acontece quando o budget é consumido. Sem uma política escrita, a decisão de pausar features vs continuar é sempre política — não dados.
# Error Budget Policy — Checkout Service Documento: v1.2 | Owner: SRE Platform | Aprovado: 2024-01-10 ## SLO - Availability: ≥ 99.5% em janela rolling de 30 dias - Latência P95: ≤ 500ms em janela rolling de 30 dias ## Estados do Error Budget ### 🟢 Verde (> 50% budget restante) - Time pode lançar features normalmente - Deploy a qualquer momento dentro da janela de mudança (Ter-Qui 10h-16h) - Post-deployment monitoring: 30 min ### 🟡 Amarelo (10-50% budget restante) - Deploy limitado: máximo 1 feature/semana - Código de alto risco (mudança de DB, integração externa) requer revisão adicional - SRE co-aprova PRs de infra - Post-deployment monitoring: 2h com rollback automático disponível ### 🔴 Vermelho (< 10% budget restante) - Feature freeze: ZERO novos deploys de features - Apenas hotfixes de confiabilidade e segurança crítica - Daily standup inclui SRE lead obrigatoriamente - Time de produto notificado e impacto comunicado em roadmap - Revisão de causa raiz obrigatória antes de retornar ao amarelo ### 🚨 Budget esgotado (0%) - Freeze total: apenas rollbacks e hotfixes de segurança P0 - Post-mortem obrigatório em 48h - Plano de ação com milestones em 7 dias - Escalonamento para VP Engineering se não resolver em 14 dias ## Exceções - Patches de segurança crítica (CVE CVSS ≥ 9.0): sempre permitidos - Releases regulatórios (compliance, LGPD): aprovação explícita de VP Eng + CTO
Grafana: dashboard de SLO
# Grafana dashboard: SLO tracker (JSON model resumido)
# Panels principais para um dashboard de SLO:
panels:
# 1. SLO Gauge — "Estamos dentro do SLO?"
- title: "SLO Compliance (30d)"
type: gauge
query: |
sum(increase(http_requests_total{job="checkout",status!~"5.."}[30d]))
/
sum(increase(http_requests_total{job="checkout"}[30d]))
thresholds: [0.995: green, 0.99: yellow, 0: red]
# 2. Error Budget Remaining
- title: "Error Budget Restante"
type: stat
query: |
(
sum(increase(http_requests_total{job="checkout",status!~"5.."}[30d]))
/
sum(increase(http_requests_total{job="checkout"}[30d]))
- 0.995
) / 0.005 * 100
unit: percent
# 3. Burn Rate (1h)
- title: "Burn Rate (1h)"
type: timeseries
query: |
(1 - job:slo_checkout_success_rate:ratio_rate1h) / 0.005
alert_threshold: 14.4
# 4. Error rate breakdown por status code
- title: "Errors por Status Code"
type: timeseries
query: |
sum by(status_code) (
rate(http_requests_total{job="checkout",status=~"5.."}[5m])
)Q&A — perguntas típicas de entrevista SRE
P: Como você explica error budget para um gerente de produto que quer lançar uma feature urgente com o budget quase esgotado?
R: O error budget é como crédito: quando acabar, qualquer deploy de feature aumenta o risco de uma nova falha que violará o SLA com penalidades financeiras. Lançar com budget quase esgotado é como dirigir com pneu furado — pode funcionar, mas o próximo problema vira crise. Proposta concreta: lançar via feature flag para 1% dos usuários (canary), monitorar por 24h, e só expandir se o budget não cair. Isso fecha a urgência do produto sem arriscar o SLA.
P: Qual é a janela ideal para um SLO — semanal, mensal ou trimestral?
R: 30 dias rolling é o padrão do mercado. Janelas muito curtas (7d) tornam o budget muito sensível a um único incidente. Janelas muito longas (90d) demoram para dar sinal. Rolling window é melhor que janela fixa (Janeiro 1–31) porque evita comportamentos perversos no final do mês onde times correm para recuperar budget antes do reset.
P: Como lidar com SLO de serviço que depende de terceiro (AWS, Stripe)?
R: Separar o SLI: medir separadamente a taxa de falhas atribuível ao serviço próprio vs ao terceiro. Adicionar timeout + circuit breaker (módulo anterior). Excluir do error budget eventos de force majeure documentados (outage de cloud, falha de backbone de rede) — mas isso deve estar explícito na error budget policy, não ser decidido ad hoc. Nunca definir SLO mais alto que o SLA do fornecedor crítico.
- SLI = o que medir. SLO = alvo interno. SLA = contrato com penalidade. Sempre: SLA < SLO < 100%.
- Error budget transforma confiabilidade em decisão de negócio objetiva — sem política, é sempre briga política.
- Alertas simples de "% de erros" falham: disparam em spikes curtos e ignoram degradação silenciosa. Use multi-window multi-burn rate.
- Burn rate 14.4× esgota budget de 30d em 2 dias → P1. Burn rate 3× esgota em 10d → investigação assíncrona.
- Toil > 50% do tempo = time não consegue criar automação = ciclo vicioso. Projetos de redução de toil têm ROI direto em confiabilidade.
- SLO deve refletir a arquitetura real, não aspirações. Comece conservador e aperte com maturidade.
Quiz rápido
4 perguntas · Acerte tudo e ganhe o badge 🎯 Gabarito