Métricas RED e USE: os frameworks que cobrem 90% dos casos
- ⬜🔍 Observability: os 3 pilares (logs, métricas, traces) e por que não basta(Observabilidade & SRE)
Recomendamos completar os pré-requisitos antes de seguir, mas nada te impede de continuar.
"O que eu devo monitorar?" é a pergunta que todo dev faz na primeira vez que sobe algo pra produção. Resposta ruim: "tudo que parecer útil". Resposta boa: dois frameworks complementares que cobrem 90% dos casos — RED pra serviços, USE pra recursos. Combinados com os Four Golden Signals do Google, você tem um checklist testado em escala massiva.
Este módulo mostra os 3 frameworks, quando aplicar cada um, por que percentiles matam média, e armadilhas clássicas (histogramas com buckets errados, averaging p99s, labels explosivos).
RED Method: para serviços (request-driven)
Proposto por Tom Wilkie (Weaveworks, depois Grafana Labs) em 2016. Simplifica drasticamente o "o que medir em cada serviço":
| Métrica | O que é | Pergunta que responde |
|---|---|---|
| Rate | Requisições por segundo (throughput) | Quanto tráfego o serviço recebe? |
| Errors | Taxa de erros (req com falha / total) | Quantas requisições falham? |
| Duration | Distribuição de latência (percentiles) | Quão rápido o serviço responde? |
# app.py — instrumentação RED com prometheus_client
from prometheus_client import Counter, Histogram
import time
REQUESTS = Counter(
"http_requests_total",
"Total de requisições HTTP",
["method", "endpoint", "status"], # cardinalidade controlada
)
DURATION = Histogram(
"http_request_duration_seconds",
"Latência de requisições HTTP",
["method", "endpoint"],
buckets=(0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10),
)
async def middleware(request, call_next):
start = time.time()
status = "500"
try:
response = await call_next(request)
status = str(response.status_code)
return response
finally:
elapsed = time.time() - start
REQUESTS.labels(request.method, request.url.path, status).inc()
DURATION.labels(request.method, request.url.path).observe(elapsed)# Queries PromQL que derivam as 3 métricas RED
# Rate (req/s nos últimos 5min)
sum by (endpoint) (rate(http_requests_total[5m]))
# Errors (% erros 5xx)
sum by (endpoint) (rate(http_requests_total{status=~"5.."}[5m]))
/ sum by (endpoint) (rate(http_requests_total[5m]))
# Duration p99
histogram_quantile(0.99,
sum by (endpoint, le) (rate(http_request_duration_seconds_bucket[5m]))
)USE Method: para recursos (resource-driven)
Proposto por Brendan Gregg (Netflix, performance guru) em 2012. Para cada recurso do sistema (CPU, memória, disco, NIC, connection pool, thread pool, fila):
| Métrica | O que é | Indica |
|---|---|---|
| Utilization | % do tempo que o recurso está ocupado | Quão "cheio" está — alto pode ser normal se não tem fila |
| Saturation | Quantidade de trabalho em fila / não atendido ainda | Demanda excede capacidade — causa latência |
| Errors | Eventos de erro específicos do recurso | Hardware/driver falhando |
Exemplos:
| Recurso | Utilization | Saturation | Errors |
|---|---|---|---|
| CPU | % CPU user+system | Run-queue length, load average | Throttles, machine checks |
| Memória | % RAM usada | Swap usage, kswapd busy | ECC errors, OOM kills |
| Disco | % busy (iostat util) | IO queue depth, avg wait | Bad sectors, retries |
| Rede (NIC) | % bandwidth usada | TX/RX queue dropped packets | CRC errors, collisions |
| Connection pool (DB) | % connections active | Waiters on acquire | Timeouts acquiring |
| Thread pool | % threads busy | Queue size de tasks pendentes | Task rejections |
Gotcha comum — Saturation é mais útil que Utilization: CPU a 95% é normal num batch job. Mas CPU a 80% com load average 40 em máquina de 8 cores (saturação) = sistema em colapso. Utilization alto sem saturation = eficiência. Utilization moderado com saturation alta = gargalo.
Four Golden Signals (Google SRE Book)
Definidos no livro Site Reliability Engineering (Google, 2016, cap. 6). É o superset que sintetiza RED e USE aplicado a serviços:
| Signal | Descrição | RED/USE equivalente |
|---|---|---|
| Latency | Tempo de resposta — separe success vs failure | Duration do RED |
| Traffic | Demanda — req/s, tx/s, user-session count | Rate do RED |
| Errors | Taxa de falhas — explícitas E implícitas (latency alta) | Errors do RED |
| Saturation | "Cheio" do sistema — recurso mais saturado limita performance | Saturation do USE |
Prática Google SRE: todo serviço deve ter dashboard com os 4 signals visíveis em uma tela. Alertas baseados em SLOs derivados deles. Esse é o padrão de fato pra "production-grade service".
Quando usar RED vs USE vs Golden Signals
| Contexto | Framework principal |
|---|---|
| Serviço HTTP/gRPC/fila-request | RED |
| Recurso de infra (CPU, disco, pool) | USE |
| Serviço + visão de capacidade | Golden Signals (RED + Saturation) |
| Banco de dados | USE + métricas específicas (slow queries, locks, replication lag) |
| Fila/broker (Kafka, SQS, RabbitMQ) | USE (queue depth, consumer lag) + Traffic |
| Batch jobs | Runtime, success rate, throughput de items |
| Mobile/web client | RUM — Largest Contentful Paint, CLS, FID, INP |
- → consome
- → saturação vira latência
- Fora da AWS
- Conceito de arquitetura
- Compute
- Integração de apps
A conclusão é que os dois conjuntos não competem: RED diz QUE dói e USE diz ONDE. Time que só tem RED vira caça ao tesouro no incidente; time que só tem USE alerta em CPU alta e ignora o usuário na fila.
- 1 · RED responde "o usuário está sofrendo?". Taxa, erros e duração descrevem o que chega e o que sai. É a visão de fora, e é dela que sai o alerta que acorda alguém.
- 2 · USE responde "por que ele está sofrendo?". Utilização, saturação e erros do recurso descrevem a capacidade. É a visão de dentro, e é dela que sai o diagnóstico.
- 3 · A ponte é a fila. Utilização em 100% não é problema por si — recurso ocupado é recurso usado. O que dói é a saturação: trabalho esperando. E é ela que aparece do outro lado como cauda de latência.
- 4 · Alertar em utilização é o erro clássico. Um alerta de "CPU acima de 80%" dispara em serviço saudável e silencia em serviço com fila crescendo em outro recurso. Alerte no sintoma do usuário, diagnostique no recurso.
- 5 · O SLO decide o que é urgente. Sem ele, todo número parece importante e ninguém sabe se 300 ms é bom. Com ele, RED vira "quanto do orçamento já gastamos" e USE vira "onde mexer".
Na prática, combine. Um dashboard típico de serviço tem:
- Topo (RED/Golden): Rate, Error rate, Latency p50/p95/p99
- Meio (Saturation): CPU, memory, connection pool, thread pool, queue depth
- Fundo (dependencies): DB query p99, cache hit ratio, external API error rate
- Lateral (deploy/release): build version, feature flag state
Armadilhas clássicas
#1: Reportar média ao invés de percentile. Média esconde outliers. Sempre use percentis (p50, p95, p99, p99.9). Não tire média de p99s entre réplicas — é matematicamente incorreto. Use histogramas agregáveis (Prometheus) + histogram_quantile.
#2: Buckets de histograma errados. Prometheus histogram precisa de buckets pré-definidos. Se seu p99 real é 2s mas o maior bucket é 1s, p99 reportado vira "+Inf" ou ruim. Escolha buckets que cubram 10x o p99 esperado. Ex: (0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10).
#3: Label explosion. {user_id}, {trace_id}, {session} em métricas matam Prometheus. Use events/logs pra essas dimensões, não métricas.
#4: Errors não inclui "latency igual a timeout". Request que durou 30s e timed out no cliente conta como error, mesmo que servidor respondeu 200. Instrumente no cliente também, não só no servidor.
#5: Esquecer saturation. Sem saturation, você só vê o problema depois que virou latency/error. Saturation antecipa.
Quando aplicar o método orientado a requisições e quando o orientado a recursos?
Exemplo: aplicando tudo numa API real
# dashboard-checkout-api.yaml — estrutura de um dashboard production-grade
panels:
- title: "Traffic (RED:Rate)"
query: |
sum by (endpoint) (rate(http_requests_total{service="checkout"}[5m]))
- title: "Error Rate (RED:Errors, Golden:Errors)"
query: |
sum(rate(http_requests_total{service="checkout",status=~"5.."}[5m]))
/ sum(rate(http_requests_total{service="checkout"}[5m]))
alert: "> 1% por 5min"
- title: "Latency p50/p95/p99 (RED:Duration, Golden:Latency)"
queries:
- histogram_quantile(0.50, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))
- histogram_quantile(0.95, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))
- histogram_quantile(0.99, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))
- title: "CPU Saturation (USE)"
query: |
sum by (pod) (rate(container_cpu_usage_seconds_total{pod=~"checkout-.*"}[5m]))
/ sum by (pod) (kube_pod_container_resource_limits{resource="cpu",pod=~"checkout-.*"})
alert: "> 85% por 10min"
- title: "DB Connection Pool Saturation (USE)"
query: |
pool_connections_active{pool="checkout_db"}
/ pool_connections_max{pool="checkout_db"}
alert: "> 90%"
- title: "DB Query p99 (RED aplicado ao DB)"
query: |
histogram_quantile(0.99,
sum by (query_type, le) (rate(db_query_duration_seconds_bucket[5m]))
)
alert: "> 500ms por 10min"
- title: "Queue Saturation (SQS consumer lag)"
query: aws_sqs_approximate_number_of_messages_visible{queue="checkout-events"}
alert: "> 10000 por 15min"Decisões reais
📋 API REST nova, quero dashboard mínimo útil
RED te dá 'o serviço tá bem?'. Saturation te antecipa problemas ('CPU em 90%, logo vai degradar'). Com 5 painéis, você já está 90% lá. Adicione mais conforme necessidade — evite dashboard com 50 painéis que ninguém lê.
Alt: Golden Signals completo — Essencialmente o mesmo — use como checklist.
📋 Serviço de batch processing (worker consumindo fila)
Workers não têm 'latência por request' tradicional — são throughput-oriented. Métricas chave: queue depth (consumer lag), items processed/s, error rate, duração média por item (se variável). RED clássico não se aplica bem.
Alt: RED tradicional — Meh — o "request" do worker é ambíguo.
📋 Monitorar Postgres em produção
Postgres tem idiossincrasias que genéricos não cobrem: VACUUM lag, bloat, replication slot size, xid wrap. Use postgres_exporter + queries customizadas. USE cobre CPU/disco/memória mas faltam as métricas de DB que matam.
Alt: Só USE genérico — Perde alertas específicos de DB — risco.
Perguntas típicas (Q&A)
Quantas métricas por serviço são "muitas"?
Regra prática: ~20-50 métricas distintas por serviço. Inclui RED, saturation de recursos, métricas de negócio (orders_created_total, revenue_cents). Se tem 200 métricas, provavelmente há duplicação ou lixo.
Dashboards por serviço ou por time?
Ambos. Service dashboards (detalhe, on-call do serviço). Team/squad dashboards (visão macro dos serviços que o time dono). Exec dashboards (uptime, revenue impact). Camadas servem audiências diferentes.
Devo alertar em todas as métricas?
Não. Alerte em consequências de usuário (latency/error afetando SLO) e leading indicators (saturation alto) que te dariam tempo de agir. Alertar em cada spike de CPU = alert fatigue = alerta ignorado quando realmente importa.
Como monitorar serviço async/event-driven?
Adapte RED: "Rate" = events processed/s, "Errors" = events falhados, "Duration" = tempo end-to-end (produção → consumo). Adicione "age" do evento mais antigo não processado (alerta se passa de threshold).
Métricas de negócio no mesmo lugar?
Sim! Orders/s, signup rate, conversion% são as MAIS importantes. Quando elas caem, algo está errado mesmo que RED/USE estejam verdes. Misture técnicas com negócio nos dashboards principais.
Take-aways:
Próximo módulo: o SDK unificado pra instrumentar tudo — OpenTelemetry end-to-end.
Perguntas frequentes
❓ O que medir num serviço, no mínimo?
❓ Por que média de latência engana?
❓ Saturação é a mesma coisa que utilização?
Fixando
Qual é a armadilha clássica ao usar média como métrica de latência?
O que a saturação mede, e por que ela é o sinal mais preditivo?
Terminou de ler?
Marcar como concluído registra o XP, mantém sua sequência e coloca 3 cartas deste módulo na fila de revisão espaçada.
Próximos passos sugeridos
Temas deste módulo
Discussão
Carregando comentários…