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? |
Cada endpoint/serviço:
Rate ───► http_requests_total{service, endpoint, status} (Counter)
Errors ───► derivado do Rate: filtro por status 5xx / total
Duration ───► http_request_duration_seconds{service, endpoint} (Histogram)
Dashboard por serviço:
┌──────────────────────────────────────────┐
│ Rate (req/s): ████▇▆▅▅▄▃▃▃▃ 200 │
│ Error rate: ────────── 0.2% │
│ Duration p50: ────────── 45ms │
│ Duration p95: ▅─────── 180ms│
│ Duration p99: ▇▅── 320ms│
└──────────────────────────────────────────┘# 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 |
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 |
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 |
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
(0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10).{user_id}, {trace_id}, {session} em métricas matam Prometheus. Use events/logs pra essas dimensões, não métricas.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.
- RED (Rate, Errors, Duration): o mínimo pra todo serviço request-driven.
- USE (Utilization, Saturation, Errors): o mínimo pra todo recurso.
- Four Golden Signals (Google SRE): Latency + Traffic + Errors + Saturation. Superset operacional.
- Sempre percentiles (p50, p95, p99), nunca média. Histogramas agregáveis com histogram_quantile.
- Saturation antecipa problemas que viram latência/error. Monitorar o "quão cheio" o recurso.
- Cuidado com label explosion em métricas — use events/traces pra contexto rico.
- Complemente frameworks com métricas de negócio (orders/s, revenue, conversion).
Próximo módulo: o SDK unificado pra instrumentar tudo — OpenTelemetry end-to-end.
Quiz rápido
4 perguntas · Acerte tudo e ganhe o badge 🎯 Gabarito