Observability · 13/08/2026
Limites de Cardinalidade em OpenTelemetry Expõem o Trade-off Real: Segurança de Memória versus Precisão de Queries em Observabilidade
OpenTelemetry implementa limites de cardinalidade para proteger processos de crescimento de memória ilimitado, mas essa proteção silencia queries de filtro e agrupa atributos, quebrando SLOs e alertas sem sinais visuais de degradação.
O que está acontecendo
O metrics SDK do OpenTelemetry foi projetado com uma guardrail fundamental: quando um stream métrico recebe muitas combinações únicas de atributos, um limite de cardinalidade ativa automaticamente, evitando que a memória cresça indefinidamente. Esse mecanismo funciona bem em seu objetivo defensivo.
O problema não está na proteção em si, mas na sombra que ela deixa: quando esse limite é acionado (overflow), o valor total da métrica permanece correto, porém queries que filtram ou agrupam por atributos começam a undercount. Silenciosamente. Sem alertas embutidos. Sem mudanças visuais óbvias nos dashboards até que você investigue.
Essa assimetria quebra um contrato implícito que toda plataforma de observabilidade deve honrar: visibilidade não significa apenas coletar dados, significa garantir que dados filtrados reflitam a realidade operacional.
Insights e Riscos
Subcontagem silenciosa em dimensões: Uma métrica que controla requisições por
status_code,endpoint, eregionpode estar perdendo 30% dos dados em uma dimensão específica sem que dashboards sinalizem essa perda. SLOs que usampercentile(latency, 0.99)agrupados por endpoint começam a subcontar outliers reais.Monitoramento de SLOs falsamente positivo: Se o seu SLO filtra por atributo (ex: "99% de requisições bem-sucedidas no
/checkout"), mas o overflow mata dados dessa combinação específica, você vê sucesso artificial. Incidentes reais ficam invisíveis até que o impacto atinja a camada de negócios.Alertas baseados em atributos ficam deaf: Alertas que agrupam por
deployment_idoutenant_idcontinuarão disparando, mas como metric streams individuais são dropados, a cobertura real cai sem que o estado do alerta mude.Trade-off intencional, não bug: O limite existe porque cardinalidade sem controle mata observabilidade de forma mais rápida e completa que qualquer overflow silencioso. Uma OOM leva todo o agent de observabilidade. Subcontagem em um subset de atributos é, paradoxalmente, o "mal menor" em design.
Impacto em arquiteturas de multi-tenancy: Sistemas que usam
tenant_idouaccount_idcomo atributo de cardinalidade alta enfrentam esse trade-off mais cedo. Um overflow no atributo de tenant afeta SLOs globais sem alterar o estado agregado.
O que muda na prática
Para Engenheiros de Plataforma / SRE:
Você precisa instrumentar observabilidade da observabilidade. Monitore o próprio metrics SDK para detectar quando overflow está acontecendo. Procure por:
- Discrepâncias entre
metric.sum()(totalizador, sempre correto) emetric.sum().group_by(attribute)(agregação granular, potencialmente subconta). - Implementar um canary: compare a soma de valores agrupados com o valor total. Se divergirem, overflow está ativo.
- Considerar reduzir cardinalidade antes do limite ativar, removendo atributos de baixa relevância em tempo de inicialização do tracer.
Para Arquitetos de Observabilidade:
O limite de cardinalidade não é configurável por acaso. A maioria das implementações usa 2000 ou 2048 combinações únicas por métrica. Se suas topologias de atributo podem gerar 50k+ combinações, você está no caminho errado. Repensar a dimensionalidade:
- Colapse dimensões: em vez de
method,endpoint,status_code,region,version, use apenasmethod,status_codee agregueendpointem traces, não em métricas. - Use labels cardinais-baixos:
status_code(3-5 valores) é seguro.user_id(milhões de valores) não. - Reserve atributos de alta cardinalidade para spans e traces, não métricas.
Para DevOps/MLOps:
Quando você deploy um agente OpenTelemetry, estabeleça alertas assimétricos. Não confie em "métrica reporta X", confie em "métrica reporta X e nenhum overflow ocorreu". Ferramentas como Prometheus ou backends que suportam OpenTelemetry podem expor otelcol_metrics_cardinality_dropped ou métricas análogas. Alertar sobre isso com severidade alta.
Para ambientes de ML/dados, onde atributos como model_version, dataset_id, experiment_tag podem explodi em cardinalidade, considere usar span attributes para essas dimensões e reservar métricas para observáveis realmente agregáveis.
Conclusão direta
OpenTelemetry sacrifica uma certa ilusão de precisão granular para garantir que observabilidade não mate seu próprio processo. É uma troca defensável, mas somente se você a entender e detectar quando ela acontece. O risco real não está no mecanismo de proteção em si, está na falsa confiança que builds em cima de métricas filtradas sem verificar se o overflow está em ação.
Se você constrói SLOs, alertas ou dashboards que dependem fortemente de filtros por atributo, você está um overflow silencioso de distância de cegos operacionais. Como você está atualmente monitorando se seus limites de cardinalidade já foram acionados?
Fontes
- [Fonte: Blog on OpenTelemetry] Metric cardinality limits in OpenTelemetry: a practical guide