Single-binary install (most homelabs)

# Get the latest release
VM_VER=v1.108.0
curl -L "https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/${VM_VER}/victoria-metrics-linux-amd64-${VM_VER}.tar.gz" \
    | tar -xz
sudo install victoria-metrics-prod /usr/local/bin/victoria-metrics

# Or via apt repos (community-maintained) / official Docker image
docker pull victoriametrics/victoria-metrics:latest

# Run
sudo mkdir /var/lib/victoria-metrics
sudo /usr/local/bin/victoria-metrics \
    -storageDataPath=/var/lib/victoria-metrics \
    -retentionPeriod=180d \
    -httpListenAddr=:8428

Or systemd:

[Unit]
Description=VictoriaMetrics
After=network.target

[Service]
User=victoriametrics
ExecStart=/usr/local/bin/victoria-metrics \
    -storageDataPath=/var/lib/victoria-metrics \
    -retentionPeriod=180d \
    -httpListenAddr=:8428 \
    -memory.allowedPercent=60
Restart=always

[Install]
WantedBy=multi-user.target

Configure as a Prometheus remote-write target

The simplest migration: keep Prometheus, point its remote_write at VictoriaMetrics, set Prometheus's local retention to short (24h), let VictoriaMetrics handle long-term storage.

# prometheus.yml
remote_write:
  - url: http://vm:8428/api/v1/write
    queue_config:
      max_samples_per_send: 10000
      capacity: 50000
      max_shards: 30

Now Prometheus continues to scrape; VictoriaMetrics stores the long-term data. Grafana points at VictoriaMetrics's PromQL endpoint (http://vm:8428) for dashboards and at Prometheus for recent recording rules.

Or skip Prometheus entirely: vmagent

For new deployments, drop Prometheus and use vmagent (VictoriaMetrics's scraper) directly:

vmagent \
    -promscrape.config=/etc/vmagent/scrape.yml \
    -remoteWrite.url=http://vm:8428/api/v1/write \
    -httpListenAddr=:8429

The scrape.yml is the same format as Prometheus's. vmagent is dramatically lower-memory than Prometheus's scraper at scale (uses streaming + lower per-target overhead).

Query with Grafana

Add a Prometheus data source in Grafana; URL = http://vm:8428. Existing dashboards work unchanged. PromQL queries execute against VictoriaMetrics's MetricsQL engine — mostly identical, with extensions for some common patterns.

Why it's denser than Prometheus's TSDB

Several reasons add up:

  • Better Gorilla-style compression for floats + delta encoding for timestamps.
  • Index uses inverted indexes per label, more compact than Prometheus's TSDB index.
  • Aggressive merging of small parts; less metadata overhead per series.
  • No bloated WAL — VM uses an LSM-tree-style layout.

Typical observed compression: a Prometheus TSDB that's 100 GB becomes 10-15 GB in VictoriaMetrics for the same data and retention.

MetricsQL: the extended PromQL

MetricsQL is a superset; useful additions:

# sum without zero-result series (common pain in PromQL)
sum(rate(http_requests_total[5m])) without ()

# Per-second derivative (PromQL's irate is min 2 samples; deriv() works on any window)
deriv(node_filefd_allocated[5m])

# label_set / label_del / label_map for relabel-style ops in queries
label_map(some_metric, "instance", "old=new")

# range_avg, range_sum, etc. for cumulative ops across the query range
range_avg(my_metric[1d])

# Step-style queries: rollup_rate, default_value, drop_empty_series
drop_empty_series(sum by (foo) (some_metric))

MetricsQL is fully PromQL-compatible — queries written for Prometheus run unchanged. The extensions are opt-in.

Alerting

Use vmalert (VictoriaMetrics's alerting component) or keep Prometheus's Alertmanager:

vmalert \
    -datasource.url=http://vm:8428 \
    -notifier.url=http://alertmanager:9093 \
    -rule=/etc/vmalert/rules/*.yml \
    -remoteWrite.url=http://vm:8428 \
    -remoteRead.url=http://vm:8428

Same rule format as Prometheus. The -remoteWrite + -remoteRead options let vmalert persist recording-rule results to VM and re-load alert state on restart.

Cluster mode

For very large fleets (10k+ scrape targets), VictoriaMetrics's cluster mode separates concerns:

  • vmstorage — stores data; horizontally scaled, each holding a shard
  • vminsert — accepts writes, distributes to vmstorage
  • vmselect — serves queries, fans out to vmstorage + merges results

Each tier scales independently. Adding capacity is "add another vmstorage / vminsert / vmselect pod." For homelab scale, the single-binary mode is sufficient.

Multi-tenancy

VictoriaMetrics's tenant ID at write/read time gives per-tenant isolation:

# Write to tenant 1234
POST http://vminsert:8480/insert/1234/prometheus/api/v1/write

# Read from tenant 1234
GET http://vmselect:8481/select/1234/prometheus/api/v1/query?query=up

Per-tenant retention, rate-limits, and quotas via runtime config. Useful for "multiple teams sharing one metrics infrastructure with cost / quota separation."

Long-term storage backups

# Built-in incremental backup to S3 / GCS / Azure / fs
vmbackup -storageDataPath=/var/lib/victoria-metrics \
    -snapshotName=daily-$(date +%Y%m%d) \
    -dst=s3://my-bucket/vm-backups/

Snapshot-based; consistent point-in-time copies; incremental after the first. Restore with vmrestore.

VictoriaMetrics vs alternatives

  • Prometheus — the original. Great for short-retention scraping. Storage gets expensive past ~30 days.
  • VictoriaMetrics — faster + denser; native long-term storage; Prometheus-compatible. Drop-in for most use cases.
  • Thanos — Prometheus + an object-storage backend + a query fan-out. More complex; tighter Prometheus integration. Lost ground to VictoriaMetrics in the past few years.
  • Cortex / Mimir — Grafana Labs's distributed Prometheus alternatives; similar shape to VM cluster mode; more complex; Grafana Cloud uses Mimir internally.
  • InfluxDB — different query language (InfluxQL / Flux); strong in IoT; less natural for Prometheus-style infrastructure metrics.

For self-hosted Prometheus that's struggling with disk usage, query latency on long ranges, or memory consumption — VictoriaMetrics is the most straightforward upgrade in 2026.