Deployment guide

Self-Host VictoriaMetrics on a VPS: Long-Term Prometheus Storage

Deploy on a VPS Cloud →

Tutorial

Self-Host VictoriaMetrics on a VPS: Long-Term Prometheus Storage

Self-hosting7 min read4 steps

Prometheus is excellent at collecting metrics and much less so at keeping them. By default it retains fifteen days of history, and extending it grows the disk and memory of the very machine doing the monitoring. VictoriaMetrics is an open-source time series database (Apache-2.0 licensed) that takes over: it receives metrics via `remote_write`, compresses them and keeps them for months, while answering the same query API as Prometheus. This guide installs it as a single Docker container on a VPS, protects it with a password, puts it behind an HTTPS reverse proxy and connects Prometheus and Grafana to it.

Contents· Why dedicated storage for your metrics1/13
  1. 01Why dedicated storage for your metrics
  2. 02What VictoriaMetrics brings
  3. 03VictoriaMetrics versus Prometheus local storage
  4. 04Prerequisites
  5. 05Install VictoriaMetrics with Docker Compose
  6. 06Without a password, the database is open for writing
  7. 07Send metrics from Prometheus
  8. 08Query VictoriaMetrics from Grafana
  9. 09Retention, disk and backup
  10. 10Send metrics without Prometheus
  11. 11Keep cardinality under control
  12. 12Update VictoriaMetrics
  13. 13One-click install from the ServOrbit Marketplace

Why dedicated storage for your metrics

A standalone Prometheus mixes two jobs: scraping your services' metrics every fifteen seconds, and storing them. The first is light; the second grows with every series and every day of history. You end up cutting retention to a few weeks, and the question "was latency already this high last quarter?" goes unanswered.

VictoriaMetrics separates the two. Prometheus — or Grafana Alloy, vmagent, Telegraf — keeps scraping, then sends every sample to VictoriaMetrics, which compresses and keeps it. Because it answers the Prometheus query API, Grafana queries it without changing a single dashboard.

What VictoriaMetrics brings

  • Prometheus-compatible — remote_write target, Prometheus query API, Grafana data source with no plugin.
  • PromQL and MetricsQL — your PromQL queries work as-is; MetricsQL adds handier functions.
  • Compact storage — strong series compression, several months of retention on a modest disk.
  • Multi-protocol — InfluxDB line protocol, Graphite, OpenTSDB, OpenTelemetry, CSV and JSON import.
  • vmui interface — series exploration, graphs, cardinality analysis and slowest queries.
  • A single binary — one container, no external dependency, a few tens of megabytes of RAM at rest.

VictoriaMetrics versus Prometheus local storage

Scroll the table

VictoriaMetricsPrometheus alone
Typical retentionSeveral months to several yearsFifteen days by default
Centralise several serversYes, via remote_writeNo, one instance per scope
Query languagePromQL and MetricsQLPromQL
Ingestion formatsPrometheus, InfluxDB, Graphite, OpenTSDB, OTLPPrometheus scraping
GrafanaPrometheus data sourcePrometheus data source
Target scrapingPossible, but left to Prometheus or vmagentYes, that is its job

Prerequisites

An Ubuntu 24.04 VPS with 1 GB of RAM is enough to start; plan 2 GB and more disk if you centralise many servers. You need Docker with the Compose plugin, and a domain name pointing to the VPS, with nginx and an HTTPS certificate: your servers will send their metrics there and Grafana will query it, so the address must be stable and encrypted.

Ideally, install VictoriaMetrics on a machine separate from the servers it monitors: if it goes down with them, you lose precisely the data that explains the outage.

Install VictoriaMetrics with Docker Compose

  1. Prepare the directory and the password

    Create the application directory and a .env file holding the password of the admin user.

    mkdir -p /opt/victoriametrics && cd /opt/victoriametrics
    echo "ADMIN_PASSWORD=$(openssl rand -hex 16)" > .env
    chmod 600 .env
  2. Write the docker-compose.yml

    The port is published on the loopback interface only: only nginx reaches it. The two -httpAuth options protect every endpoint — interface, queries and ingestion. -retentionPeriod=12 keeps twelve months of data.

    services:
      victoriametrics:
        image: victoriametrics/victoria-metrics:v1.155.0
        restart: unless-stopped
        ports:
          - "127.0.0.1:8428:8428"
        command:
          - -storageDataPath=/storage
          - -retentionPeriod=12
          - -httpAuth.username=admin
          - -httpAuth.password=${ADMIN_PASSWORD}
          - -selfScrapeInterval=30s
        volumes:
          - victoriametrics-data:/storage
    
    volumes:
      victoriametrics-data: {}
  3. Start the container

    Startup takes less than a second. The log should show "started VictoriaMetrics" followed by the start of self-scraping.

    docker compose up -d
    docker compose logs --tail 20
  4. Publish over HTTPS with nginx

    In your domain's vhost (certificate obtained with certbot), proxy to the local port. Raise client_max_body_size: remote_write batches quickly exceed the default limit.

    location / {
        proxy_pass http://127.0.0.1:8428;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        client_max_body_size 64m;
    }

Without a password, the database is open for writing

Without the -httpAuth options, anyone who knows the address can read all your metrics and write fake ones, or even delete series through the admin API. Keep authentication enabled, and never publish port 8428 directly on the public IP: always go through the HTTPS reverse proxy.

Send metrics from Prometheus

On each server running Prometheus, add a remote_write block to prometheus.yml, then reload Prometheus. It keeps scraping as before and duplicates every sample to VictoriaMetrics.

remote_write:
  - url: https://metrics.example.com/api/v1/write
    basic_auth:
      username: admin
      password: "<ADMIN_PASSWORD>"

Then check that data arrives: the up series of your targets should answer. Recent samples appear after about thirty seconds, a normal delay VictoriaMetrics applies to instant queries.

curl -u admin:<ADMIN_PASSWORD> \
  'https://metrics.example.com/api/v1/query?query=up'

Query VictoriaMetrics from Grafana

In Grafana, add a data source of type Prometheus with the URL https://metrics.example.com, tick Basic auth and enter the admin user and the password. Your existing dashboards — Node Exporter Full, for example — work unchanged, over the whole depth of history kept.

To explore without Grafana, open https://metrics.example.com/vmui: the built-in interface graphs queries, lists series and shows, in the cardinality tab, which metrics cost the most storage.

Retention, disk and backup

Retention is set with -retentionPeriod: a bare number counts months, and the suffixes d, w or y count days, weeks or years. Disk usage depends mostly on the number of active series and the scrape frequency: measure it after a week (du -sh on the volume) rather than estimating it. To back up, the official vmbackup tool takes consistent snapshots without stopping the database; otherwise, stop the container before copying the volume.

Send metrics without Prometheus

Prometheus is not mandatory. VictoriaMetrics directly accepts the Prometheus text format, the InfluxDB line protocol, Graphite, OpenTSDB and OpenTelemetry. An application can therefore push its own counters with a single HTTP call — handy for a business metric, a backup script or a scheduled job that does not run long enough to be scraped.

curl -u admin:<ADMIN_PASSWORD> \
  -d 'orders_total{shop="casa"} 1284' \
  https://metrics.example.com/api/v1/import/prometheus

If you already use Telegraf, point its InfluxDB output to https://metrics.example.com with the same credentials: VictoriaMetrics presents itself as an InfluxDB database for writes. To scrape targets without installing Prometheus on every machine, the lightweight vmagent reads the same scrape_configs as Prometheus and ships everything via remote_write; it buffers samples on disk if VictoriaMetrics is briefly unreachable.

Keep cardinality under control

The cost of a time series database does not depend on the number of samples but on the number of series: every unique combination of metric name and labels creates one. A label carrying a user ID, an IP address or a full URL multiplies series by the thousand, and that is what fills memory and disk — with VictoriaMetrics as with Prometheus.

The Cardinality tab of vmui lists the metrics and labels producing the most series. Check it after connecting a new service: a label with unbounded values is fixed at the source, in the application or with a metric_relabel_configs rule on the Prometheus side, before it fills months of storage.

Update VictoriaMetrics

The project ships a new release several times a month, with detailed release notes. The storage format stays compatible across versions: updating means changing the image number in docker-compose.yml, then restarting the container. The data volume is kept, and the short gap during the restart is absorbed by the Prometheus or vmagent buffer, which resends pending samples.

cd /opt/victoriametrics
docker compose pull
docker compose up -d

One-click install from the ServOrbit Marketplace

The ServOrbit Marketplace installs VictoriaMetrics on your VPS without a command line: it deploys the official container, generates the password of the admin user, enables authentication on every endpoint and publishes the interface over HTTPS on a subdomain of your domain or on the VPS's free subdomain. The password is shown in your client area; all that is left is to add the remote_write block to your servers and the data source in Grafana.

Your metrics for the long run, on your VPS

A ServOrbit Ubuntu 24.04 VPS with 1 GB of RAM is enough to start VictoriaMetrics. One-click install from the Marketplace, HTTPS on your domain or on the VPS's free subdomain, password generated for you.

Need help?

Browse our help center and FAQ, or reach our team — callback, WhatsApp or email. Support in French, English and Arabic.

Message us on WhatsAppopens in a new tab