Should the Browser SDK support the Metrics SDK? #266
Replies: 4 comments
-
|
This seems like a good summary @martinkuba thanks for putting it together. I certainly don't have all the answers, but can offer a few thoughts.
This is the thing that I've been reconsidering the most. While it is the classic problem, I think that emitting metrics and letting collectors/pipelines/backends discard attributes as needed is a much more powerful, flexible, and extensible approach. Not every user will want this, and not every backend will handle this gracefully, but I now think it makes sense to NOT exclude metrics for these reasons.
I'm not sure it's fair to include this, because most questions that will be asked will require aggregation, regardless if the data is events, metrics, or something else entirely. I agree that it's probably necessary, but it's not the job of the sdk so I wouldn't sweat that here.
This is another classic question. Sure, you can collapse all of observability into logs...some very successful companies were grown from that very idea alone 🙃 . But nowadays, I think we try and use data models that more closely match the thing we're trying to observe, and that also match the way we talk about and think about software. Metrics, spans/traces, events, and profiles (and hell, to some degree vitals and sessions and inventory and I'm sure many more) are all higher level concepts that we apply to software domains. When we think about a measurement, or like a gauge, we get this mental model of what that is and what it provides (a numeric value that changes over time) and how it might be used (to draw a chart or to compute an average). Sure, you could provide events that contain those same measurements, but why? Dealing with a more precise type is often more meaningful, more useful. It takes away some of the interpretation. I think that coming up with guidance on when to use which type has been a longstanding challenge. It would be nice to have an intelligent rubric for this for every time this comes back up. 😁 |
Beta Was this translation helpful? Give feedback.
-
What is that makes the server-side Metrics SDK heavyweight? Does tree-shaking work for this package, and would that be enough if users are just using deltas?
Is there a path where a metrics collector would just work if we emit metrics from the browser SDK? Wouldn't it try to aggregate by job/instance which wouldn't make sense for the browser?
We should only use metrics if not retaining context is acceptable. At the end of the day nobody is going to go through a gigantic list of events looking at individual web vital reports. People will always look at aggregates for spikes, patterns, etc, and if they find something they want to investigate the would want to find individual exemplars. If you're trying to count page views per session or interactions with certain elements you probably don't care about individual interactions with context. In any case if this is difficult for us to define imagine how hard is for users trying to implement the SDK, so yes we should always provide guidance. I would also favor simplicity in the SDK over extra configuration in the collectors, given that it wouldn't matter how easy we do things for collectors if nobody is emitting telemetry. |
Beta Was this translation helpful? Give feedback.
-
|
@martinkuba thanks for starting this discussion on the design of metrics for use in client instrumentation. I was originally opposed to it, but now have a different view as I realize the value of Metrics API in creating custom metrics. App developers include custom metrics in server-side apps without worrying about the underlying implementation, and it would be great to provide the same ease of creating custom metrics in client-side apps as well. Regarding cumulative vs delta, agree on making delta the default temporality for the reasons mentioned. However, note that if the deltas arrive late they might be dropped or misaligned. On the topic of lightweight metrics SDK, we should also evaluate if having separate connections per signal is acceptable in client environments (browser and mobile). Given that events aggregation into metrics is needed anyway, one option is to ship metrics as events in the SDK. This can be an optional component for those that want to use it.
I think we should leave this out of this discussion, as one should use metrics when discrete events are not needed. Note that metrics API supports adding exemplars to the data points, which can be used to attach attribution information. |
Beta Was this translation helpful? Give feedback.
-
|
Hi guys! I will adding two angles to the events vs metrics discussion that I think haven't been emphasized enough: 1. Schema vs schemaless contract The Metrics API enforces a typed contract at the instrumentation point —
With metrics, the SDK guarantees the shape. With logs-as-metrics, the pipeline guarantees the shape — and the pipeline is usually owned by a different team than the one writing the instrumentation. 2. Stateful vs stateless processing cost The "convert events to metrics in the Collector" path is fundamentally stateful: the Collector has to track per-client state to aggregate over time. As @martinkuba noted for cumulative→delta conversion, memory grows with the number of active browser sessions. At scale that's a non-trivial infra cost, and it's a cost that scales with traffic, not with the number of metrics defined. Delta metrics emitted directly from the browser flip this: the Collector becomes stateless (sum deltas, forward). The aggregation cost moves to a place that's already designed to handle it (the metrics backend), and the Collector stays cheap and horizontally scalable. So the events-only path isn't really "simpler" — it just relocates complexity from the SDK into a stateful Collector tier that someone has to operate. TL;DR: I'd vote for supporting Metrics SDK with delta as default. Events still win for Web Vitals and anything where attribution context matters (agree with @joaquin-diaz on that), but for counters/histograms of business or interaction data, the typed + stateless path is materially better. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Background
The OTel Browser SDK currently does not include the Metrics SDK. Instead, we recommend generating metrics from logs/events downstream (e.g., in the Collector using connectors like
signaltometrics). This was based on the reasoning that:However, this creates friction for teams that want to use a metrics backend without access to Collector configuration. There are also use cases where client-side metric instruments would be natural — for example, counting user interactions or tracking custom business metrics using familiar counter/histogram APIs.
This discussion explores whether and how we could support the Metrics SDK in the Browser SDK.
Challenge 1: Cumulative vs. delta temporality
The default aggregation temporality in OTel is cumulative — each export sends the total accumulated value since the metric stream started. This creates problems at scale with browser clients:
Per-client series churn: Each browser session produces its own cumulative series that lives ~30 minutes and goes stale. With thousands of users, this creates massive series churn in the backend.
Aggregation across clients is hard with cumulative: If multiple clients share the same series identity (same
job, same metric name), the backend sees interleaved cumulative values from different clients and interprets every decrease as a counter reset. The data becomes meaningless.A Collector can fix this, but it's expensive: To aggregate cumulative from many clients, the Collector must track per-client state (remember the last cumulative value), compute deltas, sum them, and re-emit — essentially converting to delta anyway, while maintaining memory proportional to the number of active clients.
Delta temporality solves this: With delta, each export is self-contained (just the increment since last export). A Collector can sum deltas from all clients into a single aggregated series. No per-client state tracking needed.
Recommendation
If we support the Metrics SDK in the browser, delta should likely be the default temporality. Delta makes aggregation across many short-lived client instances feasible — a Collector can trivially sum deltas without tracking per-client state.
Note: Prometheus doesn't natively support delta, so a Collector with
deltatocumulativeprocessing would be needed for Prometheus backends. OTLP-native backends may handle delta natively.Challenge 2: Resource cardinality across clients
Browser Resource attributes can be high cardinality when aggregated across all clients:
However, the impact depends on how the backend handles Resource attributes:
job/instance. All clients collapse into the same series. Not a cardinality problem at the backend.resource_to_telemetry_conversionor similar promotion: All Resource attributes become labels, causing cardinality explosion. Requires selective promotion of only the attributes needed as dimensions.This is a solvable pipeline problem (filter/reduce dimensions in the Collector or backend), not a fundamental SDK design problem.
Challenge 3: Mutable entities and the metrics Resource
This challenge is covered in a separate discussion: Handling mutable entities. In summary, entity attributes that change during the SDK's lifetime (session ID, page URL) need to be excluded from the MeterProvider's Resource. For those that should be metric dimensions (e.g., page URL for per-route metrics), they can be injected as data point attributes at record time.
Conditions for client-side metrics to work
For the Metrics SDK to work in the browser, the following conditions need to be met:
Open questions
Should we provide a "lightweight metrics SDK" for browsers? One that defaults to delta temporality, uses a static Resource, and is optimized for bundle size — rather than using the full server-side Metrics SDK.
What is the recommended pipeline for teams without Collector access? The current recommendation requires a Collector to convert events to metrics. If we support the Metrics SDK, teams could send metrics directly — but delta temporality still likely requires a Collector for Prometheus backends. Is there a simpler path?
When should you use events vs. metrics? Even if we support the Metrics SDK, events remain better for some use cases (Web Vitals with rich attribution context, single-observation measurements). Should we provide guidance on when to use which?
Beta Was this translation helpful? Give feedback.
All reactions