VictoriaMetrics is a time series database that is compatible with Prometheus: it scrapes the same targets, accepts Prometheus remote write, and answers PromQL queries through the Prometheus HTTP API, while using far less RAM and disk. In this tutorial you will install single-node VictoriaMetrics on Ubuntu 24.04, run it as a systemd service that scrapes Node Exporter, query the data, connect Grafana, and set up backups with vmbackup.
Prerequisites
To follow this tutorial you need:
- A server running Ubuntu 24.04 LTS (x86_64), for example a CubePath VPS, with at least 2 GB of RAM and fast (SSD or NVMe) storage.
- A non-root user with
sudoprivileges. - Optionally, Grafana installed on the same server or reachable from it, for Step 6.
The single-node version handles millions of active time series on one machine and is the right choice for almost every setup. The cluster version (vminsert, vmselect, vmstorage) only makes sense when one server can no longer hold your data.
Step 1 - Downloading VictoriaMetrics
VictoriaMetrics ships as a single static binary on its GitHub releases page. Set the version you want to install (check the releases page for the latest one) and download the archive and its checksum file:
cd /tmp
VM_VERSION=v1.152.0
curl -fLO "https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/${VM_VERSION}/victoria-metrics-linux-amd64-${VM_VERSION}.tar.gz"
curl -fLO "https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/${VM_VERSION}/victoria-metrics-linux-amd64-${VM_VERSION}_checksums.txt"
Verify the download:
sha256sum --ignore-missing -c "victoria-metrics-linux-amd64-${VM_VERSION}_checksums.txt"
victoria-metrics-linux-amd64-v1.152.0.tar.gz: OK
The archive contains one binary called victoria-metrics-prod. Extract it and install it as /usr/local/bin/victoria-metrics:
tar -xzf "victoria-metrics-linux-amd64-${VM_VERSION}.tar.gz"
sudo install -m 0755 victoria-metrics-prod /usr/local/bin/victoria-metrics
Check the version:
victoria-metrics -version
victoria-metrics-20260911-125958-tags-v1.152.0-0-g540b91da03
Step 2 - Creating a user, directories and a scrape configuration
Create a system user for the service, a data directory and a configuration directory:
sudo useradd --system --no-create-home --shell /usr/sbin/nologin victoriametrics
sudo install -d -o victoriametrics -g victoriametrics -m 0750 /var/lib/victoria-metrics
sudo install -d -m 0755 /etc/victoria-metrics
VictoriaMetrics can scrape targets itself using the same scrape_configs syntax as Prometheus, so you do not need a separate Prometheus server. To have something useful to scrape, install Node Exporter from the Ubuntu repository. It exposes CPU, memory, disk and network metrics on port 9100:
sudo apt update
sudo apt install prometheus-node-exporter
Confirm it is serving metrics:
curl -s http://localhost:9100/metrics | grep -m1 node_load1
node_load1 0.08
Now create the scrape configuration:
sudo nano /etc/victoria-metrics/scrape.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: node
static_configs:
- targets: ["localhost:9100"]
labels:
host: "your_hostname"
Replace your_hostname with a name that identifies this server. To scrape other servers later, add their ip:9100 addresses to targets.
Step 3 - Running VictoriaMetrics as a systemd service
All VictoriaMetrics settings are command-line flags. Create a systemd unit:
sudo nano /etc/systemd/system/victoria-metrics.service
[Unit]
Description=VictoriaMetrics single-node time series database
Documentation=https://docs.victoriametrics.com/
After=network-online.target
Wants=network-online.target
[Service]
User=victoriametrics
Group=victoriametrics
ExecStart=/usr/local/bin/victoria-metrics \
-storageDataPath=/var/lib/victoria-metrics \
-retentionPeriod=1y \
-httpListenAddr=127.0.0.1:8428 \
-promscrape.config=/etc/victoria-metrics/scrape.yml \
-selfScrapeInterval=15s
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
LimitNOFILE=1048576
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadWritePaths=/var/lib/victoria-metrics
[Install]
WantedBy=multi-user.target
The flags used:
-storageDataPath: where the database lives.-retentionPeriod=1y: data older than one year is deleted automatically. The value accepts suffixes such as90d,6Mor2y; a bare number means months.-httpListenAddr=127.0.0.1:8428: listen only on localhost. VictoriaMetrics has no authentication by default, so do not expose port 8428 publicly.-promscrape.config: the scrape file from Step 2. SendingSIGHUP(systemctl reload) re-reads it without a restart.-selfScrapeInterval=15s: VictoriaMetrics also stores its own metrics, which the Grafana dashboard in Step 6 uses.
Start the service:
sudo systemctl daemon-reload
sudo systemctl enable --now victoria-metrics
Check that it is healthy:
sudo systemctl status victoria-metrics --no-pager
curl http://127.0.0.1:8428/health
OK
List the scrape targets and their state:
curl -s http://127.0.0.1:8428/targets
job="node" (1/1 up)
state=up, endpoint=http://localhost:9100/metrics, labels={host="your_hostname",instance="localhost:9100",job="node"}, scrapes_total=4, scrapes_failed=0, last_scrape=3.1s ago, scrape_duration=12ms, samples_scraped=312, error=
If a target shows state=down, the error= field explains why.
Step 4 - Querying metrics
VictoriaMetrics implements the Prometheus query API, so any tool that speaks PromQL works against it. Newly written samples become visible to queries after about 30 seconds.
Run an instant query:
curl -s http://127.0.0.1:8428/api/v1/query --data-urlencode 'query=up{job="node"}'
{"status":"success","data":{"resultType":"vector","result":[{"metric":{"__name__":"up","host":"your_hostname","instance":"localhost:9100","job":"node"},"value":[1790241600,"1"]}]},"stats":{"seriesFetched": "1","executionTimeMsec":1}}
Calculate CPU usage over the last five minutes as a percentage:
curl -s http://127.0.0.1:8428/api/v1/query \
--data-urlencode 'query=100 * (1 - avg by (host) (rate(node_cpu_seconds_total{mode="idle"}[5m])))'
VictoriaMetrics also includes a web UI, vmui, at /vmui/, with a query editor, graphs, and a cardinality explorer. Because the service listens only on localhost, open it through an SSH tunnel from your workstation:
ssh -L 8428:127.0.0.1:8428 your_user@your_server_ip
Then browse to http://localhost:8428/vmui/ on your workstation.
To see which metrics use the most series (useful when disk usage grows faster than expected), query the TSDB status endpoint:
curl -s 'http://127.0.0.1:8428/api/v1/status/tsdb?topN=5' | python3 -m json.tool | head -30
Step 5 - Receiving data from Prometheus (optional)
If you already run Prometheus servers, you can keep them for scraping and alerting and send their data to VictoriaMetrics for long-term storage. Add a remote_write block to each prometheus.yml:
remote_write:
- url: http://your_vm_host:8428/api/v1/write
Prometheus must be able to reach port 8428. If it runs on another machine, change -httpListenAddr to the VictoriaMetrics server's private IP address, restart the service, and allow only the Prometheus server through the firewall:
sudo ufw allow from prometheus_server_ip to any port 8428 proto tcp
After reloading Prometheus, check that samples are arriving:
curl -s http://127.0.0.1:8428/metrics | grep '^vm_rows_inserted_total{type="promremotewrite"}'
The counter should increase every few seconds.
Step 6 - Connecting Grafana
Grafana uses VictoriaMetrics through its built-in Prometheus data source:
- In Grafana, go to Connections > Data sources > Add data source and choose Prometheus.
- Set Prometheus server URL to
http://localhost:8428(or the private address of the VictoriaMetrics server). - Click Save & test. Grafana should report that it successfully queried the Prometheus API.
Then import two community dashboards through Dashboards > New > Import:
- 1860, Node Exporter Full, for the server metrics collected in Step 2.
- 10229, VictoriaMetrics single-node, to monitor VictoriaMetrics itself (ingestion rate, disk usage, active series).
Step 7 - Backing up the data
VictoriaMetrics can create instant snapshots of its data directory, and the vmbackup tool copies a snapshot to a backup location. Both tools come in the vmutils archive:
cd /tmp
curl -fLO "https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/${VM_VERSION}/vmutils-linux-amd64-${VM_VERSION}.tar.gz"
tar -xzf "vmutils-linux-amd64-${VM_VERSION}.tar.gz" vmbackup-prod vmrestore-prod
sudo install -m 0755 vmbackup-prod /usr/local/bin/vmbackup
sudo install -m 0755 vmrestore-prod /usr/local/bin/vmrestore
If you opened a new shell since Step 1, set VM_VERSION again first.
Create a directory for the backups:
sudo install -d -o victoriametrics -g victoriametrics -m 0750 /var/backups/victoria-metrics
Run a backup. vmbackup asks the running server to create a snapshot, copies it to the destination and removes the snapshot afterwards:
sudo -u victoriametrics vmbackup \
-storageDataPath=/var/lib/victoria-metrics \
-snapshot.createURL=http://127.0.0.1:8428/snapshot/create \
-dst=fs:///var/backups/victoria-metrics/latest
When it finishes without errors, the backup is in /var/backups/victoria-metrics/latest. Running the same command again only copies files that changed, so it is cheap to schedule daily. -dst also accepts s3://bucket/path for S3-compatible object storage, which is a better place for backups than the same disk.
To restore, stop the service, restore into the data directory, and start it again:
sudo systemctl stop victoria-metrics
sudo -u victoriametrics vmrestore \
-src=fs:///var/backups/victoria-metrics/latest \
-storageDataPath=/var/lib/victoria-metrics
sudo systemctl start victoria-metrics
Troubleshooting
The service fails to start. Read the log with sudo journalctl -u victoria-metrics -n 50 --no-pager. An unknown flag or a YAML error in scrape.yml is reported on startup with the exact line.
A query returns an empty result right after startup. Wait 30 to 60 seconds. Recent samples are hidden from queries for about 30 seconds so that results stay consistent.
A target stays down. Test it from the VictoriaMetrics server with curl http://target_ip:9100/metrics. On the target, allow the scraper through its firewall: sudo ufw allow from your_vm_ip to any port 9100 proto tcp.
Disk usage grows quickly. Check the top metrics with /api/v1/status/tsdb or the cardinality explorer in vmui. High-cardinality labels (user IDs, request IDs, full URLs) create a new series per value; drop them at the source or with metric_relabel_configs in scrape.yml.
Memory usage is higher than expected. VictoriaMetrics uses up to 60% of system RAM for caches by default and releases it under pressure. On a server shared with other services, lower it with -memory.allowedPercent=40 in ExecStart.
Conclusion
You now have single-node VictoriaMetrics running on Ubuntu 24.04, scraping Node Exporter, answering PromQL queries, feeding Grafana dashboards, and backed up with vmbackup. As next steps, add Node Exporter to your other servers and list them in scrape.yml, schedule the backup command with a systemd timer, and set up alerting with vmalert from the same vmutils archive.
