Technology

Kubernetes generates the cardinality your metrics bill punishes.

Pods are born and die by the thousand, and every one is a new label value. Systems priced by unique series make Kubernetes the most expensive thing you run. CtrlB stores dimensions as columns, so churn costs bytes rather than multiples.

Kubernetes
Labels kept
podnamespacenodecontainerworkloaddeploy_sha
p99 by pod
812 ms
checkout-api-7f9c-2xq4
Event
OOMKilled
restart #3 · 14:22:07
OpenTelemetryPrometheusFluentdHelmetcd
Per-pod
Dimensions kept, not dropped
100M+ series
On object storage
OTel native
No proprietary agent
0 drop rules
Nothing to configure away

One deploy, two bills

Pod churn is free on bytes and brutal on series

A single rolling update replaces every replica, and every replacement mints a new label value. On per-series pricing that is a step change in your bill. On object storage it is a few hundred megabytes.

deployment/checkout-api · rolling update8 replicas · 1 deploy
old
old
old
old
new
new
new
new

Every replacement pod mints a new value for pod.

Per-series TSDBbillable
0.0M
active series after one deploy
CtrlBstorage only
0.0 GB
bytes written after one deploy
pod label keptno relabel ruleno cardinality budget
namespace · prodcheckout-api6 replicas
series0.0M1 OOM
The Kubernetes tax

Dashboards show the cluster.Investigations need the replica.

Pods churn by the thousand, and per-series pricing turns every rolling deploy into a budget event. The usual fix strips the one label you need when a single replica misbehaves.

cluster · rolling deploy
node pool · 4 nodes
OOM
per-series pricing
billable series
0.0Mseries
series multiplierdeploy ×10
replica drill-down
focus · checkout-api-7f9c-mk2d
2xq4
12% · 41%
hh8p
14% · 38%
mk2d
89% · 97%
v4rn
11% · 44%
tt3z
22% · 55%
p8wq
31% · 62%
one data layer · one query apart
correlated
Per-pod metric
p99 812 ms
checkout-api-7f9c-mk2d
Container logs
OOMKilled · restart #3
BackOff · mk2d
Request trace
checkout → payments
1.2 s span · bottleneck

Pod, node, namespace, and workload stay real dimensions — metric spike, OOM logs, and downstream trace correlate without switching tools.

Why Kubernetes breaks metrics pricing

What changes

Every pod restart mints new label values, so a rolling deploy can multiply your billable series overnight.

Keep pod, node, namespace, and workload as real dimensions, because a dimension costs storage rather than a series multiplier.

The mitigation is a relabel rule that strips pod identity — which removes exactly the dimension you need when one replica is misbehaving.

Repetitive container logs collapse into patterns automatically, so a noisy namespace becomes a short list instead of a wall.

Container logs are high-volume and mostly repetitive, so they get sampled just as an incident makes them interesting.

Logs, metrics, and traces from the cluster share one data layer, so a pod-level metric anomaly and its logs are one query apart.

Node, pod, and application telemetry land in three systems, and correlating them is manual.

Retention is a bucket lifecycle decision, so last month's incident is as searchable as this morning's.

Full-stack visibility, one data layer

Ship with the collector you already run. Keep every label. Investigate across logs, metrics, and traces without switching tools or reconciling three stores.

Step 01
node-a
node-b
node-c
OTel Collector · DaemonSet

no proprietary agent on every node

Fluent BitPrometheus scrapeOTLP gRPC
1

Ship with the collector you already run

Point your existing OpenTelemetry collector or Fluent Bit DaemonSet at CtrlB. No proprietary agent needs to go on every node.

Step 02
typical TSDB
namespace
workload
pod ✕
relabel rule required
CtrlB · Parquet
podnamespacenodeworkloadcontainer
all columns kept
metrics · live rows
podnamespacep99
checkout-api-7f9c-2xq4checkout104ms
checkout-api-7f9c-mk2dcheckout812ms
checkout-api-7f9c-v4rncheckout111ms
2

Keep every label

Pod, namespace, node, container, and workload all land as columns. There is no relabel rule to write and no cardinality budget to defend.

Step 03
investigation · same pod
checkout-api-7f9c-
metricp99 spike · one replica
812ms
logs
OOMKilled · container checkout
BackOff · restart #3
Unhealthy · readiness failed
trace
checkout
payments
ledger

1.2 s span · same request id

3

Investigate across signals

Start from a spike in a per-pod metric, pivot to that pod's logs, then to the trace that produced them, without changing tools.

In the product

Cluster overview, built on the same lake

Events, counters, and utilisation are panels over the Parquet in your bucket — not a separate metrics store that has to agree with the logs.

ctrlb · dashboards
Dashboards /Main Cluster Overview
Last 15 minutes
prod-eu

Pod events

TimePodReason
08:41:43checkout-api-7f9c-mk2dOOMKilled
08:41:41checkout-api-7f9c-mk2dBackOff
08:41:38search-indexer-5d21-p8wqStarted
08:41:22payments-worker-91af-tt3zScheduled
08:40:57checkout-api-7f9c-mk2dUnhealthy

Running pods

0
+0 vs last window↑ healthy

across 3 clusters · 41 namespaces

Restarts by namespace

checkout14payments3search1
19 restarts · 15m window
024608:2808:3208:3608:4008:44

CPU requests vs limits

46%used
46%
Used
31%
Requested, idle
23%
Headroom to limit
Drill-down

The replica that is actually broken

This is what the pod label is for. Aggregate it away to fit a cardinality budget and the middle row below stops existing — the workload just looks a bit slow.

cluster:prod-eunamespace:checkoutworkload:api
podp99restarts
checkout-api-7f9c-2xq4104 ms0
checkout-api-7f9c-hh8p98 ms0
checkout-api-7f9c-mk2d812 ms3
checkout-api-7f9c-v4rn111 ms0
Same data, pod dropped
workload p99
281 ms
4 replicas averaged

Within SLO, no alert, nothing to page on — while a quarter of your checkout traffic takes eight times longer and the pod restarts every few minutes.

What you get

Per-pod granularity

Container log patterns

Multi-cluster

Collector fleet management

Ephemeral-friendly

OpenTelemetry native

In production
GoComet · OnBe
5 sources → 1 lake

“CtrlB gives us real-time visibility into our logistics systems — I can see critical events as they unfold.” — Ayush Lodhi, CTO & Co-Founder, GoComet. At OnBe, application, infrastructure, database, load balancer, and firewall logs share one data layer.

See what changed for these teams

Questions

Only the OpenTelemetry collector, if you are not already running one. CtrlB does not require a proprietary node agent.

Yes. Metrics are stored as columns in Parquet rather than as series in a TSDB index, so adding a high-churn dimension adds bytes rather than multiplying a billable series count.

Yes. Cluster becomes a dimension like any other, so one query can span clusters, regions, and clouds.

PromQL is supported, so existing dashboards and recording rules carry over.

Put it on your own bucket and see.

Point a source at CtrlB, keep everything else where it is, and compare the same investigation side by side.