Use case

Tag everything. Query all of it.

Every metrics vendor eventually asks you to pick which tags are worth keeping. That question only exists because their storage charges by unique series. CtrlB stores metrics as columns in Parquet, so a dimension costs what its bytes cost.

100M+ series
On object storage
0 drop rules
Nothing to configure away
Every tag
Stays queryable
Bytes, not series
What cost tracks

The cardinality tax, removed

Add a dimension. Watch which side pays for it.

A TSDB charges by unique tag combination, so every dimension you add multiplies the series count and the bill. CtrlB stores each tag as a column, so the same dimensions cost what their bytes cost — and every one stays queryable.

Metric
http_requests_total+ status+ region+ tenant+ user+ model
Traditional TSDBcounting series
4unique series

bill multiplies per unique tag combination

CtrlB · columns in Parquetno ceiling
5columns

a dimension adds bytes, not a multiplier

Same tags on both sides. One bill multiplies, the other just adds.

The cardinality tax

01Traditional metric pricing counts unique tag combinations, so adding a tenant or user dimension multiplies your bill rather than your storage.

02The mitigation vendors offer is an allowlist or blocklist of tags — you still decide upfront which context to discard, you just do it in a config file.

03By the time an incident needs the dimension you dropped, the data to reconstruct it is gone.

04Teams end up not instrumenting the workflows that matter most, because the interesting ones are the high-cardinality ones.

What removing it looks like

Tag by user, tenant, device, region, endpoint, or LLM call. There is no allowlist to maintain because no tag needs permission to exist.

Series are columns in Parquet, not rows in a TSDB index, so a new dimension adds bytes rather than multiplying a series count.

Every historical tag stays queryable, so the dimension you did not think to prioritise is still there during the incident.

Cost tracks the data you wrote and the compute you used — the same drivers as the rest of your infrastructure bill.

How it works

1

Write metrics with every dimension

Emit the tags that describe your system honestly — per tenant, per model, per execution path — without pre-registering them or estimating their cardinality first.

2

Store as columns, not series

Metrics land in the same Parquet lake as logs and traces. High-cardinality tags compress as columns instead of exploding an in-memory index.

3

Slice by anything, later

Group by a dimension you never planned to group by. The query reads the columns it needs; nothing had to be indexed in advance for it to work.

What you get

No cardinality ceiling

No tag configuration

Per-tenant and per-user views

AI workload dimensions

Same lake as logs and traces

Cost you can predict

Production proof
Zepto
5–10 min → 500 ms–5 sec

Same security agent. Same S3 data. Only the query layer changed.

View customer story

Questions

There is no per-series limit in the pricing or the index. The practical bound is the storage the data occupies and the compute a query over it consumes — both of which scale linearly and predictably.

That approach separates ingestion from indexing and asks you to configure which tags stay queryable. CtrlB keeps every tag queryable because there is no separate index whose size drives the bill.

Yes. Columnar layout means a query reads only the dimensions it references, so adding unused tags to a metric does not slow down queries that ignore them.

Yes — CtrlB can sit under the metrics tooling you already use.

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.