VictoriaMetrics with Docker: Lightweight Prometheus-Compatible Monitoring with Grafana (Linux, Windows, Mac)
Before you start
- 21 min read
Boxes marked Run in terminal are what you type; plain text explains why. Check what you need first

What you get in one minute#
VictoriaMetrics is a free, open-source time series database that speaks the Prometheus language: you point your scrapers or Grafana at it and keep months of metrics in one small container.

Logo: the official VictoriaMetrics project (github.com/VictoriaMetrics/VictoriaMetrics)
It suits a home lab or small server where Prometheus uses more memory and disk than you like. The single-node version is one process with no dependencies, set up with command-line flags. It scrapes Prometheus-style targets itself and can also be long-term storage behind a Prometheus you already run.
| What | Value (official docs and registries, read October 2026) |
|---|---|
| Current version | VictoriaMetrics v1.155.0, released October 2026 (latest release) |
| Images to pin | victoriametrics/victoria-metrics:v1.155.0 and grafana/grafana:13.3.0 (both tags checked on Docker Hub) |
| Time needed | About 20 minutes plus image downloads (our estimate; Grafana is about 0.5 GB to pull) |
| Size and RAM | Measured on Windows, idle: VictoriaMetrics 156 MiB RAM, Grafana 260 MiB; VictoriaMetrics image 57 MB on disk |
| Ports | TCP 8428 (VictoriaMetrics and its vmui page), TCP 3000 (Grafana); both published on 127.0.0.1 here |
| Licence | Apache-2.0 (LICENSE at the release tag); paid enterprise features exist separately |
| Official docs | docs.victoriametrics.com and the repository |
At a glance:
- What it is: one binary that stores metrics, answers PromQL-style queries and has a built-in web page called vmui.
- What you build: VictoriaMetrics plus Grafana in one Compose file, with a scrape file for your computer's own numbers.
- The flag to know:
-retentionPeriod. The default is one month, and a bare number means months, not days. - Single-node or cluster: the docs say to try single-node first. This guide uses it.
- Backups: the official
vmbackuptool works from instant snapshots without stopping anything. - Not internet-safe by default: the docs say to keep it in private networks. Only Grafana goes behind HTTPS here.
How it fits together#
VictoriaMetrics pulls numbers from exporters, keeps them in a folder on your disk, and Grafana asks it questions when you open a dashboard.
Drawn for this guide from the official docs and our Compose file. The dashed parts are optional.
Before you start#
You need a computer that runs Docker and Docker Compose. The same Compose file works on Linux, Windows and Mac.
| System | What you need |
|---|---|
| Linux | Docker Engine with Compose v2, any x86_64 or arm64 machine, about 1 GB of free RAM and a few GB of disk |
| Windows | Docker Desktop (WSL 2 backend), PowerShell, an administrator account for the exporter in Step 4 |
| Mac | Docker Desktop, Terminal, Homebrew for the exporter in Step 4 |
Check Docker on every system:
docker --version docker compose version
Checklist:
- [ ] Ports 8428 and 3000 are free on your computer
- [ ] You have backed up any existing
~/docker_volumes/victoriametricsfolder - [ ] For the HTTPS section only: a domain with a DNS record for the server, and ports 80 and 443 free
Tested on 2026-10-31: Linux = not run, Windows = Steps 1 to 3 and the backup and restore test (Windows 11 with Docker Desktop), Mac = not run. The exporters in Step 4 and the HTTPS route were not run. Everything else comes from the official docs read in October 2026.
Step 1: Create the folders and config files#
All data lives in ~/docker_volumes/victoriametrics. You create three small config files and one .env file.
Linux#
mkdir -p ~/docker_volumes/victoriametrics/{data/vm,data/grafana,config,backups}
cd ~/docker_volumes/victoriametrics
cat > config/scrape.yml << 'EOF'
scrape_configs:
- job_name: host
scrape_interval: 15s
static_configs:
- targets: ["host.docker.internal:9100"]
EOF
cat > config/grafana-datasource.yml << 'EOF'
apiVersion: 1
datasources:
- name: VictoriaMetrics
type: prometheus
access: proxy
url: http://victoriametrics:8428
isDefault: true
jsonData:
prometheusType: Prometheus
prometheusVersion: 2.24.0
EOF
printf 'GRAFANA_ADMIN_PASSWORD=%s\nGRAFANA_UID=%s\n' "$(openssl rand -hex 16)" "$(id -u)" > .env
chmod 600 .env
Windows (PowerShell)#
$d = "$HOME\docker_volumes\victoriametrics"
New-Item -ItemType Directory -Force "$d\data\vm","$d\data\grafana","$d\config","$d\backups" | Out-Null
Set-Location $d
@'
scrape_configs:
- job_name: host
scrape_interval: 15s
static_configs:
- targets: ["host.docker.internal:9182"]
'@ | Set-Content -Encoding utf8 config\scrape.yml
@'
apiVersion: 1
datasources:
- name: VictoriaMetrics
type: prometheus
access: proxy
url: http://victoriametrics:8428
isDefault: true
jsonData:
prometheusType: Prometheus
prometheusVersion: 2.24.0
'@ | Set-Content -Encoding utf8 config\grafana-datasource.yml
$pw = -join ((48..57) + (65..90) + (97..122) | Get-Random -Count 20 | ForEach-Object { [char]$_ })
"GRAFANA_ADMIN_PASSWORD=$pw" | Set-Content -Encoding ascii .env
Mac (Terminal)#
Same commands as Linux, run in Terminal. The scrape target host.docker.internal:9100 is resolved by Docker Desktop to your Mac.
The datasource file is the one in the official Compose environment (deployment/docker/provisioning/datasources/prometheus/single.yml), with the same Prometheus type and version 2.24.0 that the Grafana integration page asks for. The scrape file points at an exporter on your computer; Step 4 starts it. Until then, VictoriaMetrics logs connection refused for that target. That is expected.
Check it worked. The folder holds config, data, backups and .env:
ls -A ~/docker_volumes/victoriametrics
On Windows, use Get-ChildItem -Force.
Tip: The Grafana admin password is the line in
.env. Read it withcat .env(Windows:Get-Content .env) and store it in a password manager.
Step 2: Write the Compose file and start everything#
One file for all three systems. It pins both images, keeps both web ports on 127.0.0.1, and adds vmbackup as an on-demand service that starts only when you ask for it.
services:
victoriametrics:
image: victoriametrics/victoria-metrics:v1.155.0
container_name: victoriametrics
restart: unless-stopped
command:
- "-storageDataPath=/storage"
- "-retentionPeriod=90d"
- "-selfScrapeInterval=10s"
- "-promscrape.config=/config/scrape.yml"
ports:
- "127.0.0.1:8428:8428"
volumes:
- ./data/vm:/storage
- ./config:/config:ro
extra_hosts:
- "host.docker.internal:host-gateway"
grafana:
image: grafana/grafana:13.3.0
container_name: grafana
restart: unless-stopped
user: "${GRAFANA_UID:-472}"
depends_on:
- victoriametrics
ports:
- "127.0.0.1:3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD}
volumes:
- ./data/grafana:/var/lib/grafana
- ./config/grafana-datasource.yml:/etc/grafana/provisioning/datasources/victoriametrics.yml:ro
vmbackup:
image: victoriametrics/vmbackup:v1.155.0
profiles: ["backup"]
depends_on:
- victoriametrics
volumes:
- ./data/vm:/storage
- ./backups:/backups
The flags, from the flag list: -storageDataPath is the data folder inside the container; -retentionPeriod=90d keeps 90 days; -selfScrapeInterval=10s records VictoriaMetrics' own metrics so you see data at once; -promscrape.config is the scrape file. host-gateway is Docker's special value for "the host", so a container can reach exporters on your computer.
Linux#
Save the file as ~/docker_volumes/victoriametrics/docker-compose.yml (for example with nano docker-compose.yml), then:
cd ~/docker_volumes/victoriametrics docker compose config -q docker compose up -d docker compose ps
Windows (PowerShell)#
Save the file as docker-compose.yml in $HOME\docker_volumes\victoriametrics (for example with notepad docker-compose.yml), then:
Set-Location "$HOME\docker_volumes\victoriametrics" docker compose config -q docker compose up -d docker compose ps
Mac (Terminal)#
Same commands as Linux:
cd ~/docker_volumes/victoriametrics docker compose config -q docker compose up -d docker compose ps
Check it worked. docker compose ps shows victoriametrics and grafana as Up. The VictoriaMetrics log (docker compose logs victoriametrics --tail 40) contains these lines (real output from our Windows test, shortened):
-retentionPeriod="90d" opening storage at "/storage" with -retentionPeriod=90d started VictoriaMetrics in 1.032 seconds started self-scraping `/metrics` page with interval 10.000 seconds started server at http://0.0.0.0:8428/
Tip: Run
docker compose config -qbefore everyup. It prints nothing when the file is valid and names the broken line when it is not.
Step 3: Look at your first numbers#
VictoriaMetrics records its own metrics, so you have something to see before any exporter runs. Self-scraped metrics become queryable about 30 seconds after the start (Quick-Start).
Linux#
curl -s "http://127.0.0.1:8428/api/v1/query?query=vm_app_version" xdg-open http://localhost:8428/vmui
Windows (PowerShell)#
curl.exe -s "http://127.0.0.1:8428/api/v1/query?query=vm_app_version" Start-Process http://localhost:8428/vmui
Mac (Terminal)#
curl -s "http://127.0.0.1:8428/api/v1/query?query=vm_app_version" open http://localhost:8428/vmui
Check it worked. The query returns JSON with "short_version":"v1.155.0" (real output from our test, shortened):
{"status":"success","data":{"resultType":"vector","result":[{"metric":{"__name__":"vm_app_version","instance":"self","job":"victoria-metrics","short_version":"v1.155.0",...},"value":[...,"1"]}]},...}
In vmui, type process_resident_memory_bytes and press Enter: you see how much memory VictoriaMetrics uses. Then open http://localhost:3000 and log in as admin with the password from .env. Under Connections, then Data sources, the entry VictoriaMetrics is already there, created from your datasource file. In our test it showed as read-only, which is normal for provisioned sources.
Tip: Grafana reads
GRAFANA_ADMIN_PASSWORDonly on its first start. Grafana's docs say the admin password is "set once on first-run". To change it later, use the profile page in Grafana, not the.envfile.
Step 4: Scrape your own computer#
An exporter is a small program that publishes your computer's numbers (CPU, memory, disk, network) on a web page. VictoriaMetrics pulls that page every 15 seconds, using the scrape file from Step 1.
Linux#
Add the official node_exporter as a container. The README says a containerized exporter needs host networking, the host process list and the root filesystem mounted read-only. Add this under services: in your docker-compose.yml:
node-exporter:
image: quay.io/prometheus/node-exporter:v1.12.1
container_name: node-exporter
restart: unless-stopped
command:
- "--path.rootfs=/host"
network_mode: host
pid: host
volumes:
- "/:/host:ro,rslave"
docker compose up -d curl -s http://127.0.0.1:9100/metrics | head -3
Windows (PowerShell)#
Install windows_exporter v0.32.1 from an administrator PowerShell. The README's command creates a firewall exception, which a container needs to reach it. It listens on port 9182.
$msi = "$env:TEMP\windows_exporter-0.32.1-amd64.msi" Invoke-WebRequest "https://github.com/prometheus-community/windows_exporter/releases/download/v0.32.1/windows_exporter-0.32.1-amd64.msi" -OutFile $msi msiexec /i $msi --% ADDLOCAL=FirewallException curl.exe -s http://localhost:9182/metrics | Select-Object -First 3
Mac (Terminal)#
Install node_exporter with Homebrew (the formula is at 1.12.1) and run it as a service on port 9100:
brew install node_exporter brew services start node_exporter curl -s http://127.0.0.1:9100/metrics | head -3
Check it worked. Open http://localhost:8428/targets. The host job should show 1/1 up. Before the exporter ran, our Windows test showed job=host (0/1 up) and this log line, which is the sign that the exporter is missing, not that VictoriaMetrics is broken:
cannot scrape target "http://host.docker.internal:9182/metrics" ... connect: connection refused
Then query node_memory_MemAvailable_bytes in vmui (Linux and Mac). For the Windows exporter, open vmui's metrics explorer at http://localhost:8428/vmui/#/metrics and browse the names that start with windows_.
Tip: On Docker Desktop, a node_exporter container reports the small Linux virtual machine behind Docker, not your PC. That is why Windows and Mac use an exporter installed on the computer itself.
Step 5: Add a dashboard in Grafana#
The VictoriaMetrics team publishes a ready dashboard on grafana.com: "VictoriaMetrics - single-node", ID 10229 (updated October 2026). It shows ingestion, memory, disk and slow queries.
Linux#
In Grafana, open Dashboards, then New, then Import, enter 10229, press Load, choose the VictoriaMetrics data source and import.
Windows (PowerShell)#
The same clicks in the browser. Nothing to type in PowerShell.
Mac (Terminal)#
The same clicks in the browser.
Check it worked. The dashboard shows panels with data. We imported it through Grafana's API in our Windows test and it was accepted; we did not look at the panels in a browser. For your computer's own numbers, the third-party dashboard "Node Exporter Full" (ID 1860) targets node_exporter; read its page first.
Tip: Pick the data source in the dashboard's top bar (the
dsvariable) if panels say "No data". Wait a minute after the first start as well.
Single-node or cluster?#
Start with single-node. The cluster docs say so themselves: use the single-node version for ingestion below about a million data points per second, because it is easier to run and scales with CPU, RAM and disk.
| Single-node (this guide) | Cluster | |
|---|---|---|
| Parts | One process | vminsert, vmselect, vmstorage |
| Good for | Home labs, small and mid-size teams | Needs beyond one machine; replication; several tenants |
| Effort | One container, flags | More services, more network traffic |
| Moving later | Data must be re-ingested into a cluster | - |
Single-node data cannot be moved into vmstorage without re-ingesting it, and backups of one cannot be restored into the other.
Retention and disk space#
-retentionPeriod takes a number and a unit: h, d, w, M (month) or y. Examples: 90d, 6M, 1y. A bare number means months: -retentionPeriod=3 keeps 93 days. The default is one month and the minimum is one day.
- Data is stored in monthly partitions. A partition outside the retention is deleted on the first day of the new month, so the disk can hold up to retention plus one month.
- You can raise retention at any time. Lowering it deletes old data in the background.
- There is no "keep forever"; the docs suggest a high value such as
100y. - Plan the disk by measuring: 10 GB after a one-day test means about 1 TB for 100 days.
- Keep at least 20% of the disk free. Below
-storage.minFreeDiskSpaceBytes(default 100000000 bytes) VictoriaMetrics goes read-only and refuses new data.
To change the flag, edit -retentionPeriod in docker-compose.yml and run docker compose up -d. Flags only change on restart.
If you already run Prometheus#
Two routes, both from the docs. VictoriaMetrics can scrape your existing prometheus.yml itself: pass it as -promscrape.config (for unsupported options, remove them or add -promscrape.config.strictParse=false). Or keep Prometheus and add remote write to its config:
remote_write: - url: http://<victoriametrics-addr>:8428/api/v1/write
Remote write can raise Prometheus memory use by about 25% (docs). For Prometheus itself, see our Docker container monitoring with Prometheus and Grafana guide. For a simpler server monitor, try Beszel or Uptime Kuma 2.
Put it behind HTTPS (with or without Traefik)#
Only Grafana needs HTTPS. Keep VictoriaMetrics on 127.0.0.1: the docs say its components belong in private networks, and port 8428 has no login by default. Local-only users can skip this section. Both routes need a domain with a DNS record for the server. The commands are the same on Linux, Windows (Docker Desktop) and Mac; only the folder style differs.
With Traefik#
On a server that already runs Traefik v3 with the Docker provider, put Grafana on the proxy network and add labels. Create the network once if it is missing:
docker network create proxy
Replace the grafana service in docker-compose.yml and add the networks block at the bottom. The host port is gone, and Grafana learns its public address through GF_SERVER_ROOT_URL (the root_url setting, which Grafana's docs say matters behind a proxy):
grafana:
image: grafana/grafana:13.3.0
container_name: grafana
restart: unless-stopped
user: "${GRAFANA_UID:-472}"
depends_on:
- victoriametrics
environment:
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD}
- GF_SERVER_ROOT_URL=https://grafana.<your-domain>/
volumes:
- ./data/grafana:/var/lib/grafana
- ./config/grafana-datasource.yml:/etc/grafana/provisioning/datasources/victoriametrics.yml:ro
networks:
- default
- proxy
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.grafana.rule=Host(`grafana.<your-domain>`)"
- "traefik.http.routers.grafana.entrypoints=https"
- "traefik.http.routers.grafana.tls=true"
- "traefik.http.services.grafana.loadbalancer.server.port=3000"
networks:
proxy:
external: true
Use your own entrypoint name if it is not https. Then run docker compose up -d.
Check it worked. curl -I https://grafana.<your-domain>/ returns an HTTP status line over HTTPS, and Grafana opens with a valid certificate.
Without Traefik: Caddy#
Choose this if you have no Traefik. Caddy gets and renews its own certificates. Caddy's docs describe automatic Let's Encrypt certificates for a public domain and tls internal, its own local certificate authority, for a home name.
Use the same Grafana service as in the Traefik block but without the labels: lines. Then create the Caddy folder and file (Windows: $HOME\docker_volumes\caddy):
mkdir -p ~/docker_volumes/caddy/{data,config}
cd ~/docker_volumes/caddy
services:
caddy:
image: caddy:2.11.7
container_name: caddy
restart: unless-stopped
ports:
- "80:80/tcp"
- "443:443/tcp"
- "443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./data:/data
- ./config:/config
networks:
- proxy
networks:
proxy:
external: true
The Caddyfile for a public domain:
grafana.example.com {
reverse_proxy grafana:3000
}
For a home-only name, use tls internal:
grafana.home.arpa {
tls internal
reverse_proxy grafana:3000
}
Start both stacks (docker compose up -d in each folder). For tls internal, each device must trust Caddy's root certificate. Caddy's command-line docs say its caddy trust command installs the root into the local trust store; with Docker you copy it out instead:
docker exec caddy find /data -name root.crt docker cp caddy:<path-from-find> ./caddy-root.crt
Install caddy-root.crt as a trusted root on each device. These OS steps are not from the Caddy docs: Windows, "Trusted Root Certification Authorities"; macOS, Keychain Access with "Always Trust"; Linux, your distribution's CA store.
Check it worked. curl -I https://grafana.example.com/ returns a status line. For a home name, the browser shows a padlock only after the root is trusted.
Tip: A certificate error usually means the name in the Caddyfile differs from the DNS record, or ports 80 and 443 do not reach Caddy.
Security and testing#
| Control | How |
|---|---|
| Ports | Keep 127.0.0.1:8428 and 127.0.0.1:3000. Never forward 8428 on your router. |
| Login for VictoriaMetrics | None by default. If other machines must reach it, use -httpAuth.username and -httpAuth.password, or the vmauth proxy the docs recommend, behind HTTPS. |
| Admin endpoints | Protect snapshots and series deletion with -snapshotAuthKey and -deleteAuthKey (docs); limit /metrics to trusted networks. |
| Exporter ports | 9100 and 9182 are open to your network once the exporter runs. Do not forward them. |
| Secrets | .env is chmod 600 on Linux and Mac. Do not commit it. |
| Backups | They contain all your metrics. Keep backups/ out of shared folders. |
Quick tests after any change:
docker compose ps docker compose logs --tail=100 victoriametrics curl -s "http://127.0.0.1:8428/api/v1/query?query=up"
On Windows use curl.exe. A healthy setup answers "status":"success".
Common mistakes#
These come from the issue tracker, the docs' warnings, our test run and common AI assistant answers.
| Mistake | Why it happens | Do this instead |
|---|---|---|
Writing -retentionPeriod=12 and expecting 12 days | A bare number means months. Issue #10181 (closed) was opened because the unit-less form is confusing | Always write the unit: 12M, 90d, 1y |
| Forgetting the retention flag | The default is one month and older data is deleted for good. Issue #9751 (closed) calls this a data-loss trap | Set -retentionPeriod in the first Compose file you write |
Running vmbackup without mounting the data folder | vmbackup looks for the snapshot at its own -storageDataPath. Issue #8739 (closed) shows cannot open snapshot at "vmdata/snapshots/..." | Mount the same ./data/vm into the backup container, as the vmbackup service here does |
| Not mounting the backup destination | The backup then goes into the container's own disk and disappears. Same issue #8739 | Mount ./backups and write to fs:///backups/... |
Typing vmbackup or vmrestore flags unquoted in PowerShell | PowerShell splits -snapshot.createURL=... at the dot. Our test returned flag provided but not defined: -snapshot | Quote every flag: "-snapshot.createURL=http://..." |
Copying data/vm/snapshots with cp or rsync | Snapshots are hard links, so a plain copy can miss data (docs) | Use vmbackup |
| Letting the disk fill up | Below -storage.minFreeDiskSpaceBytes VictoriaMetrics turns read-only and stops accepting new data | Keep 20% free, and watch disk use in the dashboard |
| Using a retention of a few days and expecting a small disk | Index data is kept in monthly partitions. Issue #10961 (closed) reports more disk than expected below one month | Measure the folder size after a week; plan for the monthly cycle |
| Publishing 8428 on all interfaces | The Quick-Start docker run publishes -p 8428:8428, which listens everywhere | Publish 127.0.0.1:8428:8428 and add a login before sharing it |
Setting the Grafana password in .env after the first start | Grafana reads admin_password only on first run | Change it in Grafana's profile page |
AI assistants: giving Prometheus flags such as --storage.tsdb.retention.time or --config.file | VictoriaMetrics has its own flags; the Go flag parser stops with flag provided but not defined, as in our vmbackup test | Use -retentionPeriod and -promscrape.config; check names with -help |
AI assistants: pointing Grafana at port 9090 or 8429, or using latest | 9090 is Prometheus and 8429 is vmagent. The single-node port is 8428 | Use http://victoriametrics:8428 and pin v1.155.0 |
Tip: When an assistant gives you a VictoriaMetrics command, compare every flag with
docker run --rm victoriametrics/victoria-metrics:v1.155.0 -help. It prints the real list.
Tip: Take a backup before every upgrade and read the release notes first.
Troubleshooting#
| Problem | Solution |
|---|---|
flag provided but not defined: -snapshot | PowerShell split the flag. Put quotes around each flag, as in the backup step |
Target host shows 0/1 up and the log says connection refused | The exporter is not running or not reachable. Start it (Step 4) and allow its port in the firewall; on Linux, a host firewall such as ufw can block the Docker network |
| Grafana shows "No data" | Check the data source URL is http://victoriametrics:8428, wait 30 seconds after a start, and run up in vmui |
| Grafana will not start on Linux and the log shows a permission error | The container user must be able to write data/grafana. Set GRAFANA_UID=$(id -u) in .env (Grafana's bind-mount docs) |
| Port 8428 or 3000 already in use | Change the left number in ports: (for example 127.0.0.1:18428:8428) |
VictoriaMetrics logs cannot read process_io_* metrics from "/proc/self/io" | We saw this once on Docker Desktop for Windows; the process kept running. The docs do not explain it |
| No data after you lowered retention | Data outside the new period is deleted in the background, not at once |
cannot fallocate ... operation not supported#
Our Windows test showed this when vmrestore wrote into a folder bind-mounted from the Windows disk:
cannot restore from backup: cannot preallocate data/indexdb/2026_10/parts.json: cannot fallocate 210 bytes for "/restore/data/indexdb/2026_10/parts.json.tmp": operation not supported
Restore into a named Docker volume instead (see the restore test below). On Mac with Docker Desktop we did not test; use a volume if you see the same text.
cannot open snapshot at "vmdata/snapshots/..."#
The backup container cannot see the data folder. Mount ./data/vm into it (issue #8739).
Known bugs and warnings (October 2026)#
- Issues #3236 (closed) and #10660 (open): crashes with
permission deniedorcannot move temporary fileon Windows with data on a Windows-mounted folder or a Windows container volume. Our Docker Desktop bind mount worked, but if you see these errors, use a Docker named volume. - Issue #10319 (open): disk use can grow after forced or background merges. Watch free space.
First commands for any problem: docker compose ps, docker compose logs --tail=100 victoriametrics, docker inspect victoriametrics.
Updates and backups#
Update. Read the release notes, change the tag in docker-compose.yml, then:
cd ~/docker_volumes/victoriametrics docker compose pull docker compose up -d docker compose logs --tail=50 victoriametrics
The docs say upgrades are normally safe, and skipping versions is fine unless the notes say otherwise.
Back up. vmbackup makes an instant snapshot, copies it, and deletes the snapshot. VictoriaMetrics keeps running. The backup into latest is incremental after the first run. A dated copy is a quick server-side copy of latest.
Linux#
Save this as backup.sh in the project folder:
#!/bin/sh cd ~/docker_volumes/victoriametrics || exit 1 docker compose run --rm vmbackup -storageDataPath=/storage -snapshot.createURL=http://victoriametrics:8428/snapshot/create -dst=fs:///backups/latest docker compose run --rm vmbackup -origin=fs:///backups/latest -dst=fs:///backups/$(date +%Y%m%d)
Make it executable and schedule it for 03:00 with chmod +x backup.sh and crontab -e, adding 0 3 * * * $HOME/docker_volumes/victoriametrics/backup.sh. The backup files belong to root because the container runs as root, so deleting old dated folders needs sudo.
Windows (PowerShell)#
Save this as backup.ps1. Every flag is quoted:
Set-Location "$HOME\docker_volumes\victoriametrics" docker compose run --rm vmbackup "-storageDataPath=/storage" "-snapshot.createURL=http://victoriametrics:8428/snapshot/create" "-dst=fs:///backups/latest" $day = Get-Date -Format yyyyMMdd docker compose run --rm vmbackup "-origin=fs:///backups/latest" "-dst=fs:///backups/$day"
Schedule it with Task Scheduler at 03:00, for example schtasks /Create /SC DAILY /ST 03:00 /TN "VictoriaMetrics backup" /TR "powershell -File $HOME\docker_volumes\victoriametrics\backup.ps1". We ran the two backup commands, not the scheduled task.
Mac (Terminal)#
Same backup.sh and crontab entry as Linux. On macOS, cron may need Full Disk Access; we did not test this.
Check it worked. Real output from our Windows test:
backup ... to fsremote "/backups/latest" with origin fsnil is complete; backed up 288726 bytes in 1.895 seconds remote backup copy from fsremote "/backups/latest" to fsremote "/backups/20261031" is complete
The folder backups/ then holds latest and one folder per day. Delete old dated folders yourself.
Restore test. Restore into a new, empty named volume, never over the live data, and start a throwaway VictoriaMetrics on it:
docker volume create vm-restore-test docker run --rm -v "$HOME/docker_volumes/victoriametrics/backups:/backups" -v vm-restore-test:/restore victoriametrics/vmrestore:v1.155.0 "-src=fs:///backups/latest" "-storageDataPath=/restore" docker run -d --name vm-restore-check -p 127.0.0.1:18428:8428 -v vm-restore-test:/storage victoriametrics/victoria-metrics:v1.155.0 "-storageDataPath=/storage" curl -s "http://127.0.0.1:18428/api/v1/query?query=vm_app_version" docker rm -f vm-restore-check && docker volume rm vm-restore-test
On Windows, replace the first mount path with ${PWD}\backups after changing into the project folder, and use curl.exe. In our test the restored copy answered with v1.155.0. A real recovery follows the docs: stop VictoriaMetrics, restore into the folder behind -storageDataPath, start again. On Windows that needs a named volume, because of the fallocate error above.
Performance and resources#
Measured on Windows 11 with Docker Desktop, about 12 minutes after the start, with only self-scraping: VictoriaMetrics 156 MiB of RAM and 0.4% CPU, Grafana 260 MiB and 2% CPU. The data folder was 369 KB. Real use grows with the number of series, so the numbers on your server will differ.
- Look:
docker stats --no-stream victoriametrics grafana. - Capacity: the docs ask you to leave 50% of RAM and CPU free and 20% of disk.
- Memory knobs:
-memory.allowedPercent(default 60) and-memory.allowedByteslimit how much RAM caches may use. Change them only if you must. - Claims: the project's own benchmarks claim up to 7x less RAM than Prometheus. Those are its numbers, not ours.
FAQ#
Is VictoriaMetrics free to use? Yes. The single-node and cluster versions are under Apache-2.0. A separate enterprise version adds features such as downsampling and anomaly detection.
Can it replace Prometheus? For storing and querying, yes: it accepts Prometheus remote write, reads prometheus.yml scrape files and answers the Prometheus query API. A few config sections are unsupported, so test your file.
Do I need Grafana? No. vmui, the built-in page at /vmui, runs queries and draws graphs. Grafana adds dashboards. You can use the Prometheus data source, as here, or the VictoriaMetrics data source plugin.
Can I run it on a Raspberry Pi? The Docker Hub tag has arm and arm64 images. We did not test a Pi.
Sources#
- VictoriaMetrics release v1.155.0, README, LICENSE - read October 2026
- Single-node docs at v1.155.0 (flags, retention, security, capacity planning, snapshots), Quick-Start, cluster docs and the rendered docs - read October 2026
- vmbackup and vmrestore, Grafana integration, Prometheus integration and the official Compose environment - read October 2026
- Images on Docker Hub: victoria-metrics, vmbackup, vmrestore (tag
v1.155.0checked) and grafana (tag13.3.0checked) - October 2026 - Grafana 13.3.0 release, Grafana Docker docs, Grafana configuration and dashboard 10229 - October 2026
- node_exporter v1.12.1, windows_exporter v0.32.1 and the Homebrew formula - October 2026
- Docker Compose services reference (
extra_hosts) and Compose profiles - October 2026 - Caddy release v2.11.7, tls directive, command line and conventions - October 2026
- GitHub issues #3236, #8739, #9751, #10181, #10319, #10660 and #10961 - read October 2026
Checked against the official docs on 2026-10-31.