Self-hosted service
VictoriaMetrics/metrics avatar
VictoriaMetrics/metrics

VictoriaMetrics metrics is a Prometheus client with one dependency and a smaller surface

Lightweight alternative to github.com/prometheus/client_golang

710 stars86 forksGoMIT

At a glance

What is it?
The metrics package is a Go library for exporting Prometheus format metrics without the weight of client_golang, with vmrange histograms, distinct metric sets per endpoint and push to remote storage. It suits a service that wants a metrics endpoint in a few lines, and it is not a drop-in replacement for the full Prometheus client.
Who is it for?
Adopt VictoriaMetrics metrics when you want a metrics endpoint in a Go service with a minimal dependency footprint, and stay on client_golang when you need the advanced functionality this package explicitly does not implement.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 25 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A small dependency list is the point, not a side effect

The go.mod file shows the entire dependency footprint. There are two direct requirements, github.com/valyala/histogram at v1.2.0 and golang.org/x/sys at v0.38.0, plus one indirect requirement, github.com/valyala/fastrand at v1.1.0. The module targets go 1.24.0 with a toolchain line of go1.25.5, and the tree carries a vendor directory. The README states the design goal plainly: lightweight, with a minimal number of third-party dependencies, and all of those deps are small. It links to an article about stripping dependency bloat out of the VictoriaMetrics container image, which is the context. This matters for more than download size. Every third-party package in a Go binary is code you are shipping to production, and for a library that other services import, the dependency tree you impose is multiplied across your own consumers. The set here is small enough to read, and one of them is a histogram implementation rather than a general framework.

Registering a metric takes one constructor call each

The usage example in the documentation is the fastest way to understand the API surface. A counter, a summary, a gauge and a histogram are each created by a single constructor, and the metric name may contain labels written in Prometheus format:

go
import "github.com/VictoriaMetrics/metrics"

// Register various metrics.
// Metric name may contain labels in Prometheus format - see below.
var (
	// Register counter without labels.
	requestsTotal = metrics.NewCounter("requests_total")

	// Register summary with a single label.
	requestDuration = metrics.NewSummary(`requests_duration_seconds{path="/foobar/baz"}`)
)

The gauge variant takes a callback so the value is read at scrape time rather than tracked by the library, which is the pattern you want for queue depths and similar values. The update calls are unremarkable: Inc on the counter, UpdateDuration with a start time on the summary, Update on the histogram. There is no registration ceremony, no collector interface to implement, and no separate handle to pass around, because the package keeps a global registry that the exposition function reads.

Exposing at /metrics and pushing to remote storage are both one call

Serving the metrics is a single handler. The WritePrometheus function writes the exposition output to the response writer, and the boolean argument controls whether metadata is included:

go
// Expose the registered metrics at `/metrics` path.
http.HandleFunc("/metrics", func(w http.ResponseWriter, req *http.Request) {
	metrics.WritePrometheus(w, true)
})

The same package can push instead of serve. InitPush takes a URL, an interval, an extra label set and a flag, and the documentation notes that it can push to VictoriaMetrics or to any other remote storage that accepts metrics in Prometheus text exposition format:

go
// ... or push registered metrics every 10 seconds to http://victoria-metrics:8428/api/v1/import/prometheus
// with the added `instance="foobar"` label to all the pushed metrics.
metrics.InitPush("http://victoria-metrics:8428/api/v1/import/prometheus", 10*time.Second, `instance="foobar"`, true)

The extra label is how a pushed metric is attributed to a particular instance, since a push agent is not tied to a scrape target. The final argument turns on the same metadata handling described below.

Metadata is off by default, which surprises people

By default, exposed metrics do not have TYPE or HELP meta information, and the documentation links to an issue explaining why. The fix is a call to ExposeMetadata(true), which generates TYPE and HELP for each metric. This is a deliberate choice and the FAQ states the reasoning: because this documentation is ignored by Prometheus. The HELP text is for humans, and Prometheus does not use it, so the package leaves it out to reduce the size of the exposition output. The recommended alternative is to give meaningful names to the exported metrics, referencing the Prometheus naming guidance, or to put explanatory comments in the source code. Anyone switching from a client that emits HELP text will see the difference immediately, and it is worth deciding deliberately rather than discovering it in a dashboard.

vmrange buckets replace le labels, and a compatibility histogram is offered

The histogram implementation is the most opinionated part of the package. Buckets carry vmrange labels instead of the le labels that Prometheus histograms use, and the documentation explains the reason: vmrange buckets occupy less disk space, because they do not include counters for the previous ranges. That is a storage optimisation, and it pays off for anyone keeping a year of histogram data. The cost is that Prometheus-style tooling needs a translation step. VictoriaMetrics provides a prometheus_buckets function that converts vmrange buckets to Prometheus-style buckets with le labels, which the documentation says is useful for building heatmaps in Grafana, and its histogram_quantile function handles vmrange buckets transparently. For compatibility purposes the package also provides classic Prometheus histograms with le labels through the PrometheusHistogram type. The README separately notes that the histograms are easy to use and work without any tuning, and links to a separate article on improving histogram usability for Prometheus and Grafana.

The API is deliberately not compatible with client_golang

The FAQ opens with the question most adopters will actually ask, and the answer is a design position rather than a roadmap item. The API is not compatible with github.com/prometheus/client_golang because that package is too complex and is hard to use. The limitations section says the same thing in a different direction: it does not implement advanced functionality from client_golang. The project description calls it a lightweight alternative. Taken together these three statements mean you are not getting a subset that behaves the same, you are getting a different API with a different set of trade-offs, and a migration is a rewrite of the metric definitions rather than a swap of an import path. The closest the package comes to the Prometheus vector types is the GetOrCreateCounter function, which the FAQ points at as the way to implement CounterVec, replacing the With call on a vector.

Set keeps separate metric families on separate endpoints

One feature deserves a note because it has no direct equivalent in the usual client. The package allows exporting distinct metric sets via distinct endpoints, through the Set type. The top level of the repository confirms the shape of the implementation: separate files per metric kind, including counter.go, floatcounter.go, gauge.go, histogram.go, prometheus_histogram.go, summary.go, set.go, push.go and validator.go, alongside a metrics.go core file and go_metrics.go for the standard library integration. A Set lets a service expose, say, an internal endpoint and a public endpoint with different contents from the same process, which matters when a metrics port is reachable from outside and you want to avoid publishing everything. The repository also carries platform specific process metric collectors for Linux, Darwin, Solaris and Windows, with separate cgo and non-cgo Darwin variants, plus a tinygo build variant, which is the kind of portability work that adds up across the target platforms a Go service is deployed to.

Current releases, a permissive licence, and an origin inside VictoriaMetrics

The project is not archived and the last push was on 2026-09-28, the same day as the v1.44.1 tag. Earlier tags are v1.43.1 on 2026-04-03 and v1.41.1 on 2026-02-14, so the release cadence is steady without being daily. The licence is MIT, which makes it straightforward to vendor or depend on in a commercial service, and the module path github.com/VictoriaMetrics/metrics makes the origin obvious. The README states that Metrics was extracted from the VictoriaMetrics sources, with a link to an article about creating remote storage for Prometheus. That origin explains the whole design. The library is not trying to be a general purpose Prometheus client, it is the instrumentation layer that the VictoriaMetrics server itself uses, and the vmrange histogram and the Set type are the two features that fall out of serving Prometheus queries at scale rather than the needs of an application developer. A useful comparison point is any dashboard or recording rule written against client_golang output, since the exposition format is shared but the bucket labels are not.

Editorial conclusion

Adopt VictoriaMetrics metrics when you want a metrics endpoint in a Go service with a minimal dependency footprint, and stay on client_golang when you need the advanced functionality this package explicitly does not implement. Verify first which client your existing code and dashboards assume, since the API is not compatible and the FAQ states that outright, and check the vmrange histogram behaviour against your Grafana queries before switching, because the bucket labels differ from Prometheus style.

Frequently asked questions

Why is the VictoriaMetrics metrics API not compatible with prometheus/client_golang?

The FAQ gives a direct answer: because client_golang is too complex and is hard to use. The limitations section adds that this package does not implement the advanced functionality of client_golang, so migrating means rewriting metric definitions rather than swapping an import path.

How do I expose metrics from a Go service?

Register each metric with a constructor such as metrics.NewCounter, metrics.NewGauge, metrics.NewSummary or metrics.NewHistogram, then register a handler that calls metrics.WritePrometheus on the response writer. Metrics can also be pushed to remote storage with metrics.InitPush at a given interval.

Why do my exposed metrics have no TYPE or HELP lines?

Exposed metrics do not have TYPE or HELP meta information by default, because Prometheus ignores that documentation. Call ExposeMetadata(true) to generate it, or give the metrics meaningful names and document them in the source code instead.

What are vmrange labels in VictoriaMetrics histograms?

Buckets carry vmrange labels instead of the le labels used by Prometheus histograms, and they occupy less disk space because they do not include counters for the previous ranges. For compatibility the package also provides classic Prometheus histograms with le labels through the PrometheusHistogram type.

How do I implement a CounterVec in the VictoriaMetrics metrics package?

Use GetOrCreateCounter instead of calling CounterVec.With. The FAQ points at the GetOrCreateCounter documentation and an example for the CounterVec pattern.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. VictoriaMetrics/metrics on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/victoriametrics-metrics.svg)](https://hysenlabs.com/projects/victoriametrics-metrics)

Was this useful?