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.
Why Prometheus struggles with long retention
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.
- Prometheus local storage is positioned for operational monitoring, not durable archival, per the official docs.
- Long-term history is expected to live in a remote system reached through the remote write API.
- High active-series counts drive Prometheus memory up, which is usually the first thing to break at scale.
Head-to-head on the things that matter
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 |
MetricsQL: PromQL with the sharp edges filed off
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.
Resource use and cardinality
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.
A safe migration path
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:8428- Add a remote_write block to prometheus.yml pointing at the VictoriaMetrics write endpoint, so every new sample lands in both stores at once.
- Backfill existing history by taking a Prometheus TSDB snapshot and importing it with the vmctl migration tool, so VictoriaMetrics holds the full timeline, not just data from the cutover date.
- Add VictoriaMetrics to Grafana as a Prometheus-type data source and rebuild or clone your dashboards against it, checking that panels and alerts match the Prometheus originals.
- Once the numbers agree, shorten Prometheus local retention to a few days and let VictoriaMetrics own the long-term history for good.
Do 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.
When plain Prometheus is still the right call
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.
- You only need days or a few weeks of retention and a single node comfortably holds it.
- Your series count and cardinality are modest, so memory pressure is not a problem you actually have.
- You value a single, widely documented component over squeezing out storage and RAM savings you do not yet need.
The bottom line
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.

