<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/opentelemetry-metrics-net-counters-histograms-and-imeterfactory-kira4yrde" -->

---
title: OpenTelemetry Metrics .NET: Counters, Histograms, and...
description: A practical guide to implementing OpenTelemetry metrics in .NET using the System.Diagnostics.Metrics API. Covers the four instrument types — Counter,...
canonical: https://daily.dev/posts/opentelemetry-metrics-net-counters-histograms-and-imeterfactory-kira4yrde
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: OpenTelemetry Metrics .NET: Counters, Histograms, and IMeterFactory | daily.dev
og:description: A practical guide to implementing OpenTelemetry metrics in .NET using the System.Diagnostics.Metrics API. Covers the four instrument types — Counter,...
og:url: https://daily.dev/posts/opentelemetry-metrics-net-counters-histograms-and-imeterfactory-kira4yrde
og:image: https://api.daily.dev/og/posts/kIrA4YrDe.png
og:image:alt: OpenTelemetry Metrics .NET: Counters, Histograms, and IMeterFactory
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenTelemetry Metrics .NET: Counters, Histograms, and IMeterFactory

**[We Are .NET](https://daily.dev/sources/wearedotnet)** · 17 min read · 1 upvotes · 0 comments

## Summary

A practical guide to implementing OpenTelemetry metrics in .NET using the System.Diagnostics.Metrics API. Covers the four instrument types — Counter, Histogram, ObservableGauge, and UpDownCounter — with code examples for each. Explains why IMeterFactory should be preferred over direct Meter instantiation for testability and DI lifecycle management. Shows how to wire up the OpenTelemetry SDK pipeline with AddMeter(), AddAspNetCoreInstrumentation(), AddRuntimeInstrumentation(), and exporters for Prometheus or OTLP. Also covers naming conventions, tag cardinality best practices, testing metrics with MeterListener, and performance considerations.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://www.devleader.ca/2026/07/27/opentelemetry-metrics-net-counters-histograms-and-imeterfactory>

## Questions this post answers

### What is the difference between Counter and UpDownCounter in .NET OpenTelemetry metrics?

A Counter<T> is monotonically increasing and only accepts non-negative values via Add(), representing a cumulative total like total requests served. An UpDownCounter<T> can increase or decrease by passing positive or negative values to Add(), suited for values representing a current fluctuating quantity such as active connections or items currently in a processing queue.

_Developers designing dashboards can compare instrument choices against real examples curated on daily.dev._

### Why should I inject IMeterFactory instead of calling new Meter() directly in .NET?

IMeterFactory, introduced in .NET 8 via Microsoft.Extensions.Diagnostics, integrates with the DI container's lifetime management so meters are disposed cleanly at shutdown, and it enables testing by letting you register a real factory through services.AddMetrics() and observe measurements with MeterListener without a full OpenTelemetry pipeline. Direct new Meter() usage still fits library code where DI isn't available.

_Teams standardizing on DI patterns for metrics can track practical .NET guidance like this via daily.dev._

### How do ObservableGauge callbacks work in .NET metrics and what should they avoid doing?

The ObservableGauge<T> callback is invoked by the metrics pipeline during its collection cycle rather than on every request, with the interval set by the exporter (scrape interval for Prometheus, push interval for OTLP). The callback should be fast and non-blocking, reading an already-in-memory value such as a cached count or atomic integer instead of performing database calls or external I/O.

_Engineers instrumenting runtime health indicators can follow implementation details like these through daily.dev._

## Similar posts on daily.dev

- [Creating and consuming metrics with System.Diagnostics.Metrics APIs](https://daily.dev/posts/creating-and-consuming-metrics-with-system-diagnostics-metrics-apis-bqo3wwbym) · .NET Escapades · 0 upvotes · 0 comments
- [Creating standard and "observable" instruments](https://daily.dev/posts/creating-standard-and-observable-instruments-unkdpczvb) · .NET Escapades · 1 upvotes · 0 comments
- [Dual-exporting .NET metrics with OTLP and Prometheus](https://daily.dev/posts/dual-exporting-net-metrics-with-otlp-and-prometheus-bnnpqjfa6) · OpenTelemetry · 1 upvotes · 0 comments
- [Replacing EventCounters with the new Metrics API](https://daily.dev/posts/replacing-eventcounters-with-the-new-metrics-api-uhstec3fx) · The Art of Simplicity · 0 upvotes · 0 comments

---

Tags: [#.net](https://daily.dev/tags/.net), [#observability](https://daily.dev/tags/observability), [#opentelemetry](https://daily.dev/tags/opentelemetry), [#prometheus](https://daily.dev/tags/prometheus)

[View this post on daily.dev](https://daily.dev/posts/opentelemetry-metrics-net-counters-histograms-and-imeterfactory-kira4yrde)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"OpenTelemetry Metrics .NET: Counters, Histograms, and IMeterFactory","url":"https://daily.dev/posts/opentelemetry-metrics-net-counters-histograms-and-imeterfactory-kira4yrde","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/opentelemetry-metrics-net-counters-histograms-and-imeterfactory-kira4yrde"},"datePublished":"2026-07-27T21:57:18.331Z","dateModified":"2026-09-13T19:29:31.344Z","description":"A practical guide to implementing OpenTelemetry metrics in .NET using the System.Diagnostics.Metrics API. Covers the four instrument types — Counter,...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/6b4a6242df0bd6d423a537466482975a?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/6b4a6242df0bd6d423a537466482975a?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"We Are .NET","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"We Are .NET","logo":"https://media.daily.dev/image/upload/s--BsnVOa3i--/f_auto/v1718347410/logos/wearedotnet","url":"https://daily.dev/sources/wearedotnet"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/opentelemetry-metrics-net-counters-histograms-and-imeterfactory-kira4yrde","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":".net,observability,opentelemetry,prometheus","timeRequired":"PT17M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"We Are .NET","item":"https://daily.dev/sources/wearedotnet"},{"@type":"ListItem","position":3,"name":"OpenTelemetry Metrics .NET: Counters, Histograms, and IMeterFactory"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/opentelemetry-metrics-net-counters-histograms-and-imeterfactory-kira4yrde#faq","mainEntity":[{"@type":"Question","name":"What is the difference between Counter and UpDownCounter in .NET OpenTelemetry metrics?","acceptedAnswer":{"@type":"Answer","text":"A Counter<T> is monotonically increasing and only accepts non-negative values via Add(), representing a cumulative total like total requests served. An UpDownCounter<T> can increase or decrease by passing positive or negative values to Add(), suited for values representing a current fluctuating quantity such as active connections or items currently in a processing queue. Developers designing dashboards can compare instrument choices against real examples curated on daily.dev."}},{"@type":"Question","name":"Why should I inject IMeterFactory instead of calling new Meter() directly in .NET?","acceptedAnswer":{"@type":"Answer","text":"IMeterFactory, introduced in .NET 8 via Microsoft.Extensions.Diagnostics, integrates with the DI container's lifetime management so meters are disposed cleanly at shutdown, and it enables testing by letting you register a real factory through services.AddMetrics() and observe measurements with MeterListener without a full OpenTelemetry pipeline. Direct new Meter() usage still fits library code where DI isn't available. Teams standardizing on DI patterns for metrics can track practical .NET guidance like this via daily.dev."}},{"@type":"Question","name":"How do ObservableGauge callbacks work in .NET metrics and what should they avoid doing?","acceptedAnswer":{"@type":"Answer","text":"The ObservableGauge<T> callback is invoked by the metrics pipeline during its collection cycle rather than on every request, with the interval set by the exporter (scrape interval for Prometheus, push interval for OTLP). The callback should be fast and non-blocking, reading an already-in-memory value such as a cached count or atomic integer instead of performing database calls or external I/O. Engineers instrumenting runtime health indicators can follow implementation details like these through daily.dev."}}]}
```

