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.