VictoriaMetrics vs Prometheus for Long-Term Metrics

Photo by cbowns on flickr
Not entirely, but close. VictoriaMetrics accepts the Prometheus remote write protocol and answers MetricsQL, a superset of PromQL, so most Grafana dashboards and alert rules keep working. It replaces the storage and query layer, while Prometheus or vmagent can still handle scraping. A few edge-case PromQL behaviors differ, so verify critical alerts before cutting over.
The VictoriaMetrics FAQ states it uses roughly ten times less RAM and stores data with significantly better compression for equivalent workloads. Exact ratios depend on your data shape and cardinality. The direction is consistent across independent benchmarks: smaller resident memory and smaller on-disk blocks for the same ingested series.
Yes, and that is the recommended pattern. Add a remote_write block in prometheus.yml pointing at the VictoriaMetrics write endpoint so live samples land in both. Backfill history with the vmctl tool, then point Grafana at VictoriaMetrics. Prometheus keeps short retention while VictoriaMetrics owns the long-term archive.
MetricsQL is VictoriaMetrics's query language, described in its docs as backward compatible with PromQL for most queries. It adds conveniences such as a default lookbehind window, rollup functions that return several aggregations at once, and WITH templates for reusing subexpressions. It is not a strict superset, so a small number of PromQL edge cases behave differently.
Stick with Prometheus when you only need days or a few weeks of retention, your series count and cardinality are modest, and a single node holds everything comfortably. In that case the extra moving part is not worth it. VictoriaMetrics earns its place once memory pressure, disk growth, or long retention become real constraints.

Photo by cbowns on flickr
Key Takeaway
VictoriaMetrics and Prometheus serve different jobs: Prometheus excels at short-term scraping and alerting, while VictoriaMetrics extends the same PromQL-compatible workflow to months or years of retention using roughly ten times less RAM and disk. The safest migration mirrors data with remote write, backfills history with vmctl, and only cuts over Grafana once both backends agree.
Prometheus is the default first monitoring system for almost every team that runs Kubernetes or a fleet of Linux servers. It scrapes targets, stores samples in a local time series database, and answers PromQL queries fast. The trouble starts when someone asks a simple question: how did this metric look six months ago? Prometheus was designed for reliable short-term operational monitoring, not for keeping years of history on cheap disk.
VictoriaMetrics is a time series database built to solve exactly that gap. It speaks the Prometheus remote write protocol, ingests the same scrape data, answers a superset of PromQL, and stores the same metrics using far less disk and memory. This article walks through the concrete differences that matter for long-term retention, and gives you a migration path that keeps Prometheus in place until you trust the new backend.
Prometheus stores data locally in its own TSDB format. The official storage documentation is clear that local storage is not meant to be durable long-term storage: it recommends keeping retention modest and delegating long-term history to a remote system through the remote write API. There is no built-in clustering, no replication, and the on-disk footprint grows quickly once you push retention past a few weeks on a high-cardinality setup.
The practical failure mode is memory rather than disk. As active series count climbs, so does Prometheus RAM usage, because it keeps recent chunks and index structures in memory. Teams that try to hold a year of data on a single Prometheus node usually hit an out-of-memory restart long before they run out of disk. That is the wall VictoriaMetrics is designed to remove.
The two systems overlap heavily on the day-one experience and diverge sharply once retention and cardinality grow. This table summarizes the differences that decide whether you should keep everything in Prometheus or add VictoriaMetrics as the long-term store.
| Aspect | Prometheus | VictoriaMetrics |
|---|---|---|
| Long-term retention | Local TSDB, retention kept short; long history offloaded via remote write | Designed for months to years of retention on a single dataset |
| Disk footprint | Larger per sample; grows fast with cardinality and retention | Aggressive compression; VictoriaMetrics reports roughly 10x smaller storage |
| Memory usage | Grows with active series; the usual first bottleneck | VictoriaMetrics claims about 10x less RAM for the same workload |
| Query language | PromQL | MetricsQL, a mostly compatible superset of PromQL |
| Scaling model | Single node by design; federation or remote write for scale | Single-node binary or a horizontally scalable cluster version |
VictoriaMetrics does not force you to learn a new language. It implements MetricsQL, which the documentation describes as backward compatible with PromQL for most queries while fixing several annoyances. Existing Grafana dashboards and alert rules generally keep working when you point them at VictoriaMetrics using the standard Prometheus data source.
MetricsQL adds quality-of-life features on top of PromQL. You get a sensible default lookbehind window so you can drop the explicit range in common rate expressions, rollup functions that return several aggregations in one pass, and WITH templates for naming and reusing subexpressions. It is not a strict superset, so a handful of edge-case PromQL behaviors differ, but the vast majority of real dashboards migrate without edits.
# PromQL: rate over a fixed window, verbose to read
rate(http_requests_total[5m])
# MetricsQL: same intent, plus conveniences PromQL lacks
# - default step interval, so [5m] can be omitted
rate(http_requests_total)
# - rollup functions return min/max/avg in one call
rollup_rate(http_requests_total[5m])
# - WITH templates let you name and reuse expressions
WITH (
err = rate(http_requests_total{code=~"5.."})
)
err / rate(http_requests_total) * 100Before migrating dashboards, run your busiest Grafana panels against both backends side by side for a day. MetricsQL is close enough that most panels match exactly, and the few that differ are easy to spot when the two data sources sit next to each other.
The headline numbers from the VictoriaMetrics FAQ are that it uses roughly ten times less RAM and stores data with far better compression than Prometheus for equivalent workloads. Those figures depend on your data shape, but the direction is consistent across independent benchmarks: for the same ingested series, VictoriaMetrics holds a smaller resident set and writes smaller blocks to disk. The compression comes from column-oriented encoding and delta techniques tuned for the way monitoring data actually looks, where most samples barely change from one scrape to the next, so the on-disk cost of a year of history stays manageable even on a modest server.
Cardinality is the other axis. High-cardinality label sets, such as per-request IDs or per-container labels that churn constantly, punish Prometheus memory hard. VictoriaMetrics handles churning and high-cardinality series more gracefully, which is why it is a common choice for large Kubernetes fleets where pod names and image tags create millions of short-lived series.
The lowest-risk migration keeps Prometheus running and adds VictoriaMetrics beside it as the long-term store. You mirror live data with remote write, backfill history with vmctl, and only cut over Grafana once you have verified the new backend answers correctly.
# prometheus.yml — send a live copy to VictoriaMetrics
remote_write:
- url: http://victoriametrics:8428/api/v1/write
# Backfill historical Prometheus TSDB blocks with vmctl
vmctl prometheus \
--prom-snapshot=/path/to/snapshot \
--vm-addr=http://victoriametrics:8428
# Point Grafana at VictoriaMetrics using the Prometheus data source
# URL: http://victoriametrics:8428Do not delete your Prometheus data the day you switch. Keep both systems ingesting in parallel for at least one full retention cycle so you can compare results and roll back instantly if MetricsQL returns something unexpected in an alert rule.
VictoriaMetrics is not a mandatory upgrade. For many teams, vanilla Prometheus remains the simpler and better choice, and adding another moving part is not worth it.
Prometheus and VictoriaMetrics are not really competitors at the point of collection; they are complementary. Prometheus remains an excellent scraper and short-term store, and VictoriaMetrics slots in behind it as the durable, efficient home for long-term metrics. Because it speaks remote write and a PromQL superset, the switch is additive rather than a rewrite.
If your monitoring stack is bumping into memory limits, growing disk bills, or the flat refusal to keep more than a few weeks of history, VictoriaMetrics is the pragmatic next step. Run them side by side, verify MetricsQL against your real dashboards, and cut over only when the numbers match. Keep the rollback door open until you have watched a full retention cycle pass with both backends agreeing. That is how you get long-term metrics without betting the whole observability stack on a single migration.