Skip to main contentSkip to navigation
[email protected]
Client AreaSupport
Hosting Mammoth
HostingMammothYour Data, Our Responsibility
Home
Solutions
Hosting Services
Store
Pricing
About
Blog
API
Contact

Stay Ahead of the Curve

Get the latest insights on cybersecurity, AI innovations, and enterprise data solutions delivered to your inbox.

Hosting Mammoth
HostingMammothEnterprise Solutions

Enterprise-grade data solutions. Hosting, recovery, cybersecurity, and AI-powered services for businesses worldwide.

[email protected]
Sun - Fri, 9:00am - 5:00pm

Services

  • Cloud Hosting
  • Data Recovery
  • Cybersecurity
  • Legal Support
  • MSP Services
  • Web Development
  • AI Services
  • Free Server Migration

Hosting

  • VPS Hosting (NVMe SSD)
  • VDS Hosting (NVMe)
  • Storage VPS (High SSD)
  • GPU Servers
  • Managed Services
  • Cloud Firewall
  • Load Balancer
  • One-Click Apps
  • n8n Hosting
  • Object Storage
  • FAQ

Company

  • Store
  • Pricing
  • About Us
  • Locations
  • Blog
  • Testimonials
  • Contact
  • Affiliate Program
  • White-Label
  • Terms of Service
  • Privacy Policy
  • Browser Cookies
  • SLA

Support

  • Client Area
  • Submit Ticket
  • Knowledge Base
  • Server Status
  • API Documentation

© 2026 Hosting Mammoth. All rights reserved.

Knowledge Base
Getting StartedAccount ManagementVPS HostingGPU ServersStorage VPSCloud FirewallLoad BalancerServer ManagementBilling & PaymentsSupport & TicketsAffiliate ProgramReseller ProgramMarketplace & Appsn8n HostingManaged ServicesServer MigrationAPI & DevelopersSecurityTroubleshootingGlossaryInstall Guides
  1. Home
  2. /
  3. Support
  4. /
  5. Install Guides
  6. /
  7. How To Install Victoriametrics Ubuntu
GUIDEInstall Guides

How to Install VictoriaMetrics on Ubuntu 24.04 VPS: Fast, Cost-Efficient Prometheus Alternative

27 min read

How to Install VictoriaMetrics on Ubuntu 24.04 VPS: Fast, Cost-Efficient Prometheus Alternative

VictoriaMetrics is a high-performance, open-source time series database and monitoring platform that solves the operational pain points of running Prometheus at any real scale. It ingests Prometheus remote_write natively, speaks PromQL plus its own more powerful MetricsQL dialect, and stores metrics with up to 10x better compression while using a fraction of the RAM. This guide walks you through installing VictoriaMetrics on an Ubuntu 24.04 VPS, starting with the single-node vmsingle binary, layering on vmagent for scraping and vmalert for alerting rules, wiring it into Grafana, and finally scaling out to the vmcluster architecture with replication.

Already running Prometheus? VictoriaMetrics is a drop-in long-term storage backend. You can keep Prometheus in place, add remote_write to VictoriaMetrics, and reduce your retention-related disk bill from day one.

Table of Contents

  • What is VictoriaMetrics?
  • Why Self-Host VictoriaMetrics Instead of Prometheus?
  • Prerequisites
  • Step 1: Update System Packages
  • Step 2: Download and Install vmsingle
  • Step 3: Create a systemd Service
  • Step 4: Verify the Installation
  • Step 5: Ingest Prometheus remote_write
  • Step 6: Install vmagent for Scraping
  • Step 7: Install vmalert for Alerting Rules
  • Step 8: Connect Grafana as a Data Source
  • Step 9: Explore MetricsQL Extensions
  • Step 10: Scale Out with vmcluster (Replication)
  • Performance Tuning
  • Troubleshooting
  • FAQ
  • Next Steps
  • What is VictoriaMetrics?

    VictoriaMetrics is a fast, cost-effective, open-source time series database (TSDB) and monitoring solution. It is wire-compatible with Prometheus — meaning every tool that talks to Prometheus (Grafana, kube-state-metrics, node_exporter, Alertmanager, and thousands of exporters) also talks to VictoriaMetrics — but it uses a fundamentally different storage engine designed for massive cardinality and long retention on commodity hardware.

    The project is distributed as a family of statically linked Go binaries with no external dependencies. vmsingle (the single-node binary) handles ingestion, storage, and query in one process and is what most teams start with. vmagent is a lightweight, stateless scraper and remote_write proxy that replaces the scrape side of Prometheus and supports multi-tenant relabeling, buffering, and streaming aggregation. vmalert evaluates Prometheus-style alerting and recording rules against any PromQL/MetricsQL endpoint and pushes alerts to Alertmanager. For horizontal scale, vmcluster splits the single-node binary into three components — vmstorage (stateful shards), vminsert (ingestion router), and vmselect (query fan-out) — which together support replication, multi-tenancy, and linear scale-out to billions of active time series.

    The use cases are broad. DevOps teams use VictoriaMetrics as long-term storage for Prometheus, keeping 90 days of high-resolution metrics on a single VPS where Prometheus alone would need ten times the disk. SaaS platforms use vmcluster multi-tenancy to isolate customer metrics without running a separate stack per tenant. IoT and industrial projects use it to ingest millions of data points per second from devices and sensors. Kubernetes operators use the VictoriaMetrics Operator and VMAgent/VMAlert/VMCluster CRDs as a modern replacement for the kube-prometheus-stack. And Grafana power users adopt it for the MetricsQL extensions, which add functions that PromQL cannot easily express — like rollup_rate, keep_last_value, and streaming aggregation.

    Why Self-Host VictoriaMetrics Instead of Prometheus?

    Prometheus is an excellent monitoring system, but it was deliberately designed around local storage with a 15-day default retention and a single-node architecture. Anyone running Prometheus for more than a few dozen hosts eventually hits the same four walls: memory blow-up under high cardinality, disk growth that outpaces Moore's law, single-node scale ceiling, and lack of built-in replication. VictoriaMetrics was purpose-built to fix those four problems while staying 100% wire-compatible.

    • 10x better compression — VictoriaMetrics routinely stores the same time series in one-tenth the disk space of Prometheus. On a 7-day retention window, a fleet producing 500K active series typically drops from ~120 GB (Prometheus) to ~10-15 GB (VictoriaMetrics).
    • Dramatically lower RAM usage — VictoriaMetrics uses approximately 7x less RAM than Prometheus for equivalent workloads. Ingesting 1M samples/sec with 2M active time series fits comfortably in 8 GB of RAM.
    • Faster queries at high cardinality — VictoriaMetrics is 20x faster than Prometheus for queries over high-cardinality labels, where Prometheus's index becomes a bottleneck.
    • Long retention out of the box — Pass -retentionPeriod=12 and keep a year of data on a single node. Prometheus users typically need Thanos, Cortex, or Mimir to achieve the same — each adding operational complexity.
    • Horizontal scale when you need it — vmcluster replicates and shards across commodity nodes. Move from single-node to cluster without changing your dashboards, alerts, or scrapers.
    • Built-in replication — Set -replicationFactor=2 or -replicationFactor=3 in vmcluster and survive node loss without external storage dependencies.
    • Prometheus wire-compatible — Grafana, Alertmanager, and all exporters work unchanged. You can migrate gradually by pointing Prometheus's remote_write at VictoriaMetrics and keeping both running.
    • MetricsQL extensions — A superset of PromQL adds functions for streaming aggregation, gap-filling, rollups, and histogram manipulation that make certain dashboards dramatically simpler.

    Cost Comparison: Prometheus vs. VictoriaMetrics on the Same VPS

    For a fleet producing 500K active time series with 10-second scrape intervals at 30-day retention:

    MetricPrometheus (alone)VictoriaMetrics (vmsingle)
    Disk required (30 days)~480 GB~45 GB
    RAM required at steady state~14 GB~2.5 GB
    Startup time after restart2-10 minutes< 5 seconds
    Query p99 over 7d range3-8 seconds0.2-0.6 seconds
    High-cardinality queryFrequent OOMsHandles it
    ReplicationExternal (Thanos/Mimir)Native in cluster mode
    Recommended VPS plan32 GB RAM, 1 TB disk8-12 GB RAM, 100 GB disk
    For most teams the net effect is: the same workload fits on a dramatically smaller VPS, or the same VPS now holds 10x more retention.

    Prerequisites

    Before you begin, make sure you have:

    • A VPS running Ubuntu 24.04 LTS with root or sudo access
    • SSH access to your server
    • At least 4 GB of RAM for small-to-medium fleets (8-12 GB recommended for production)
    • At least 50 GB of disk for a comfortable retention window
    • Existing Prometheus or exporters are optional — vmagent can scrape directly
    Recommended Plan: CloudCore Professional
    >
    For a single-node VictoriaMetrics stack plus vmagent and vmalert comfortably serving a mid-size fleet (up to ~1M active series, 30-60 day retention), we recommend the CloudCore Professional plan:
    >
    - 6 vCPU cores
    - 12 GB RAM
    - 100 GB NVMe SSD
    - Unmetered bandwidth
    - EUR 19.99/month
    >
    This leaves plenty of headroom for Grafana, Alertmanager, and vmalert on the same host. For fleets above 1M active series or multi-tenant SaaS deployments, see our larger plans and consider the vmcluster setup later in this guide.

    Connect to your server via SSH to get started:

    bash
    ssh root@your-server-ip

    Step 1: Update System Packages

    Start by refreshing the package index and applying any pending upgrades.

    bash
    sudo apt update && sudo apt upgrade -y

    Install the handful of tools we will need:

    bash
    sudo apt install -y curl wget tar ca-certificates ufw

    If the kernel was upgraded, reboot before continuing:

    bash
    sudo reboot

    Step 2: Download and Install vmsingle

    VictoriaMetrics publishes signed release binaries on GitHub. We will download the latest single-node build, extract it to /usr/local/bin, and create a dedicated system user.

    Export the current release version into a shell variable so the rest of the commands remain copy-pasteable. Check the releases page for the newest version.

    bash
    export VM_VERSION="v1.109.1"

    Download the single-node archive:

    bash
    cd /tmp
    wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/${VM_VERSION}/victoria-metrics-linux-amd64-${VM_VERSION}.tar.gz

    Extract and install the binary:

    bash
    tar -xzf victoria-metrics-linux-amd64-${VM_VERSION}.tar.gz
    sudo mv victoria-metrics-prod /usr/local/bin/victoria-metrics
    sudo chmod +x /usr/local/bin/victoria-metrics

    Create a dedicated system user and data directory:

    bash
    sudo useradd --system --no-create-home --shell /usr/sbin/nologin victoriametrics
    sudo mkdir -p /var/lib/victoria-metrics
    sudo chown -R victoriametrics:victoriametrics /var/lib/victoria-metrics

    Verify the binary works:

    bash
    /usr/local/bin/victoria-metrics --version

    Expected output:

    text
    victoria-metrics-20250115-000000-tags-v1.109.1-0-abcdef12

    Step 3: Create a systemd Service

    A proper systemd unit keeps VictoriaMetrics running across reboots, captures logs into journald, and gives you a single place to configure retention, storage path, and ingestion limits.

    Create the unit file:

    bash
    sudo tee /etc/systemd/system/victoriametrics.service > /dev/null <<'EOF'
    [Unit]
    Description=VictoriaMetrics single-node TSDB
    After=network-online.target
    Wants=network-online.target

    [Service] Type=simple User=victoriametrics Group=victoriametrics ExecStart=/usr/local/bin/victoria-metrics \ -storageDataPath=/var/lib/victoria-metrics \ -retentionPeriod=3 \ -httpListenAddr=:8428 \ -selfScrapeInterval=30s \ -memory.allowedPercent=60

    Restart=on-failure RestartSec=5 LimitNOFILE=1048576

    Hardening

    NoNewPrivileges=true ProtectSystem=full ProtectHome=true PrivateTmp=true

    [Install] WantedBy=multi-user.target EOF

    Key flags explained:

    • -storageDataPath=/var/lib/victoria-metrics — Where TSDB files are written. Point this at your largest disk or mounted volume.
    • -retentionPeriod=3 — Keep 3 months of data. Use 3d, 12 (months), or 1y as needed. Default is 1 month.
    • -httpListenAddr=:8428 — The HTTP port for ingestion, queries, and the built-in UI.
    • -selfScrapeInterval=30s — VictoriaMetrics scrapes its own /metrics endpoint every 30s.
    • -memory.allowedPercent=60 — Cap internal memory use at 60% of system RAM. Lower this on shared hosts.
    Reload systemd, enable the unit, and start the service:

    bash
    sudo systemctl daemon-reload
    sudo systemctl enable --now victoriametrics

    Step 4: Verify the Installation

    Check that the service is active:

    bash
    sudo systemctl status victoriametrics

    Expected output:

    text
    ● victoriametrics.service - VictoriaMetrics single-node TSDB
         Loaded: loaded (/etc/systemd/system/victoriametrics.service; enabled; preset: enabled)
         Active: active (running) since Wed 2026-04-16 10:00:00 UTC; 10s ago
       Main PID: 2345 (victoria-metric)
          Tasks: 14 (limit: 14236)
         Memory: 82.4M
         CGroup: /system.slice/victoriametrics.service
                 └─2345 /usr/local/bin/victoria-metrics -storageDataPath=...

    Probe the health endpoint:

    bash
    curl http://localhost:8428/health

    Expected output:

    text
    OK

    Open the built-in vmui in your browser (or via curl) to confirm the query engine is live:

    bash
    curl 'http://localhost:8428/api/v1/query?query=vm_rows'

    Expected JSON response:

    json
    {"status":"success","isPartial":false,"data":{"resultType":"vector","result":[{"metric":{"__name__":"vm_rows","type":"indexdb"},"value":[1744800000,"0"]}]}}

    You now have a running VictoriaMetrics node. The web UI is available at http://your-server-ip:8428/vmui/ once you open the firewall (covered in Step 8).

    Step 5: Ingest Prometheus remote_write

    The fastest way to get real data into VictoriaMetrics is to have Prometheus ship its samples via remote_write. If you have an existing Prometheus server (see our guide on how to install Prometheus on Ubuntu), edit its configuration:

    yaml
    # /etc/prometheus/prometheus.yml
    remote_write:
      - url: http://your-vm-server:8428/api/v1/write
        queue_config:
          max_samples_per_send: 10000
          capacity: 20000
          max_shards: 30

    Restart Prometheus:

    bash
    sudo systemctl restart prometheus

    Within a few seconds you should see series start flowing. Confirm by querying for a metric you know Prometheus is scraping, such as up:

    bash
    curl 'http://localhost:8428/api/v1/query?query=up' | jq .

    You should see an entry for every target Prometheus monitors. You can now safely reduce Prometheus's local retention (for example, --storage.tsdb.retention.time=1d) and let VictoriaMetrics be your long-term store.

    Writing Directly from Exporters (No Prometheus)

    VictoriaMetrics also accepts pushed samples in multiple formats directly — Prometheus exposition, InfluxDB line protocol, Graphite plaintext, OpenTSDB, and CSV. Example using the InfluxDB line protocol (handy if you are migrating from an InfluxDB deployment):

    bash
    curl -X POST 'http://localhost:8428/write' --data-binary \
      'temperature,location=office value=23.5 1744800000000000000'

    Step 6: Install vmagent for Scraping

    vmagent is the recommended replacement for the scrape side of Prometheus. It is stateless, uses far less memory, supports multi-target relabeling, and can buffer to disk if the downstream VictoriaMetrics is unreachable.

    Download the vmagent binary (shipped in the same release bundle as vmsingle — use the -utils archive or grab the dedicated vmutils build):

    bash
    cd /tmp
    wget 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
    sudo mv vmagent-prod /usr/local/bin/vmagent
    sudo mv vmalert-prod /usr/local/bin/vmalert
    sudo chmod +x /usr/local/bin/vmagent /usr/local/bin/vmalert

    Create a Prometheus-style scrape config. vmagent uses the exact same YAML schema as Prometheus, so existing configs drop in unchanged:

    bash
    sudo mkdir -p /etc/vmagent
    sudo tee /etc/vmagent/scrape.yml > /dev/null <<'EOF'
    global:
      scrape_interval: 15s
      external_labels:
        cluster: production
        replica: vmagent-1

    scrape_configs: - job_name: 'node' static_configs: - targets: ['localhost:9100']

    - job_name: 'victoriametrics' static_configs: - targets: ['localhost:8428'] EOF

    Create a persistent queue directory for when VictoriaMetrics is briefly unreachable:

    bash
    sudo mkdir -p /var/lib/vmagent
    sudo chown -R victoriametrics:victoriametrics /var/lib/vmagent /etc/vmagent

    Create the systemd unit:

    bash
    sudo tee /etc/systemd/system/vmagent.service > /dev/null <<'EOF'
    [Unit]
    Description=vmagent — VictoriaMetrics scraper
    After=network-online.target victoriametrics.service
    Wants=network-online.target

    [Service] Type=simple User=victoriametrics Group=victoriametrics ExecStart=/usr/local/bin/vmagent \ -promscrape.config=/etc/vmagent/scrape.yml \ -remoteWrite.url=http://127.0.0.1:8428/api/v1/write \ -remoteWrite.tmpDataPath=/var/lib/vmagent \ -httpListenAddr=:8429

    Restart=on-failure RestartSec=5 LimitNOFILE=1048576

    [Install] WantedBy=multi-user.target EOF

    sudo systemctl daemon-reload sudo systemctl enable --now vmagent

    Verify it is scraping:

    bash
    curl -s http://localhost:8429/targets | head -40

    Or query VictoriaMetrics to see fresh data from node_exporter:

    bash
    curl 'http://localhost:8428/api/v1/query?query=node_load1' | jq .

    vmagent's persistent queue is the unsung hero here: if vmsingle is restarted for an upgrade, vmagent continues collecting and buffers to disk until ingestion resumes — no gaps in your dashboards.

    Step 7: Install vmalert for Alerting Rules

    vmalert evaluates Prometheus-style alerting and recording rules against any PromQL/MetricsQL endpoint and forwards firing alerts to Alertmanager.

    Create a rules file:

    bash
    sudo mkdir -p /etc/vmalert
    sudo tee /etc/vmalert/rules.yml > /dev/null <<'EOF'
    groups:
      - name: host-alerts
        interval: 30s
        rules:
          - alert: HighCPU
            expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
            for: 5m
            labels:
              severity: warning
            annotations:
              summary: "High CPU on {{ $labels.instance }}"
              description: "CPU above 85% for 5 minutes (current: {{ $value | printf \"%.1f\" }}%)."

    - alert: LowDisk expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 < 10 for: 10m labels: severity: critical annotations: summary: "Disk almost full on {{ $labels.instance }}"

    - name: recording-rules interval: 30s rules: - record: instance:node_cpu:rate5m expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) EOF

    sudo chown -R victoriametrics:victoriametrics /etc/vmalert

    Create the systemd unit. Note -notifier.url points to Alertmanager — install it separately or omit the flag if you only want recording rules.

    bash
    sudo tee /etc/systemd/system/vmalert.service > /dev/null <<'EOF'
    [Unit]
    Description=vmalert — VictoriaMetrics rule evaluator
    After=network-online.target victoriametrics.service
    Wants=network-online.target

    [Service] Type=simple User=victoriametrics Group=victoriametrics ExecStart=/usr/local/bin/vmalert \ -rule=/etc/vmalert/rules.yml \ -datasource.url=http://127.0.0.1:8428 \ -remoteWrite.url=http://127.0.0.1:8428 \ -remoteRead.url=http://127.0.0.1:8428 \ -notifier.url=http://127.0.0.1:9093 \ -httpListenAddr=:8880 \ -evaluationInterval=30s

    Restart=on-failure RestartSec=5

    [Install] WantedBy=multi-user.target EOF

    sudo systemctl daemon-reload sudo systemctl enable --now vmalert

    Check the rule evaluation UI:

    bash
    curl -s http://localhost:8880/api/v1/rules | jq .

    The -remoteWrite.url flag is what makes recording rules persist: evaluated expressions are written back into VictoriaMetrics as new time series, letting your dashboards query pre-aggregated data without recomputing expensive expressions on every render.

    Step 8: Connect Grafana as a Data Source

    VictoriaMetrics speaks Prometheus wire protocol, so Grafana sees it as just another Prometheus endpoint. If you do not yet have Grafana installed, see our guide on how to install Grafana on Ubuntu.

    Before wiring Grafana, open the firewall to allow local network access (or keep 8428 internal and proxy through Grafana only):

    bash
    sudo ufw allow from 10.0.0.0/8 to any port 8428
    sudo ufw allow from 127.0.0.1 to any port 8428
    sudo ufw enable

    In Grafana:

  • Go to Connections → Data sources → Add data source.
  • Choose Prometheus (or the dedicated VictoriaMetrics data source plugin for native MetricsQL syntax highlighting).
  • Set URL to http://127.0.0.1:8428 (or your VPS's private IP + port).
  • Leave auth settings at defaults unless you front VictoriaMetrics with Nginx Basic Auth.
  • Click Save & test. You should see "Successfully queried the Prometheus API."
  • Import dashboard 1860 (Node Exporter Full) as a smoke test — every panel should populate within a minute.

    Why the VictoriaMetrics Data Source Plugin?

    The official VictoriaMetrics data source plugin adds autocomplete for the MetricsQL functions that PromQL does not have, plus a trace view for query performance debugging. For any dashboard that uses MetricsQL-only functions, install it:

    bash
    sudo grafana-cli plugins install victoriametrics-metrics-datasource
    sudo systemctl restart grafana-server

    Step 9: Explore MetricsQL Extensions

    MetricsQL is a superset of PromQL. Every PromQL query runs unchanged, but MetricsQL adds functions that dramatically simplify common dashboards.

    rollup_rate(m[5m]) — Returns three series simultaneously: min, max, and avg of the per-second rate over the window. One query, three lines on the chart.

    promql
    rollup_rate(node_network_receive_bytes_total[5m])

    keep_last_value(m) — Fills gaps caused by missed scrapes with the last known value, which is a lifesaver for spotty exporters.

    promql
    keep_last_value(up)

    interpolate(m) — Linear interpolation across missing points, perfect for smooth dashboards on low-frequency metrics.

    histogram_quantile over multiple buckets — MetricsQL's variant accepts any quantile from 0 to 1 and handles the le="+Inf" bucket more leniently than Prometheus.

    share_le_over_time(m[window], le) — Returns the share of samples below a threshold over a time window. Useful for SLO dashboards.

    promql
    share_le_over_time(http_request_duration_seconds[5m], 0.3)

    topk_last(k, m) — The top k series by their last value, without the "series swap" flicker you get from vanilla PromQL's topk.

    @ modifier in ranges — Evaluate a subquery at a fixed timestamp, enabling week-over-week comparisons in a single expression.

    Full MetricsQL reference: docs.victoriametrics.com/MetricsQL.html.

    Step 10: Scale Out with vmcluster (Replication)

    Once you approach 1-2 million active series or need replication for HA, graduate from vmsingle to vmcluster. The cluster splits into three stateless-or-stateful roles:

    • vmstorage — Stateful storage nodes. Data is sharded across them. Losing one takes its shard offline unless replication is enabled.
    • vminsert — Stateless ingestion router. Hashes each time series to replicationFactor storage nodes.
    • vmselect — Stateless query fan-out. Sends queries to all storage nodes and merges results.

    Recommended Minimal Cluster

    For basic HA with replication factor 2, you need at least two storage nodes (so a lost node does not lose data) plus vminsert and vmselect (which can share a host with storage in small deployments):

    RoleCountPort(s)
    vmstorage2+8400 (vminsert), 8401 (vmselect), 8482 (HTTP)
    vminsert2+8480
    vmselect2+8481

    Install vmstorage

    Download the cluster binaries (different archive from vmsingle):

    bash
    cd /tmp
    wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/${VM_VERSION}-cluster/victoria-metrics-linux-amd64-${VM_VERSION}-cluster.tar.gz
    tar -xzf victoria-metrics-linux-amd64-${VM_VERSION}-cluster.tar.gz
    sudo mv vmstorage-prod /usr/local/bin/vmstorage
    sudo mv vminsert-prod /usr/local/bin/vminsert
    sudo mv vmselect-prod /usr/local/bin/vmselect
    sudo chmod +x /usr/local/bin/vm{storage,insert,select}

    Systemd unit for vmstorage (run this on each storage node):

    bash
    sudo tee /etc/systemd/system/vmstorage.service > /dev/null <<'EOF'
    [Unit]
    Description=vmstorage — VictoriaMetrics cluster storage
    After=network-online.target

    [Service] Type=simple User=victoriametrics Group=victoriametrics ExecStart=/usr/local/bin/vmstorage \ -storageDataPath=/var/lib/vmstorage \ -retentionPeriod=6 \ -vminsertAddr=:8400 \ -vmselectAddr=:8401 \ -httpListenAddr=:8482

    Restart=on-failure LimitNOFILE=1048576

    [Install] WantedBy=multi-user.target EOF

    Install vminsert and vmselect

    On one or more router nodes, run vminsert and vmselect pointing at all your storage nodes. With -replicationFactor=2, vminsert writes every sample to two different storage nodes.

    bash
    sudo tee /etc/systemd/system/vminsert.service > /dev/null <<'EOF'
    [Unit]
    Description=vminsert — VictoriaMetrics cluster ingestion
    After=network-online.target

    [Service] Type=simple User=victoriametrics Group=victoriametrics ExecStart=/usr/local/bin/vminsert \ -storageNode=storage-1.internal:8400,storage-2.internal:8400 \ -replicationFactor=2 \ -httpListenAddr=:8480

    Restart=on-failure LimitNOFILE=1048576

    [Install] WantedBy=multi-user.target EOF

    bash
    sudo tee /etc/systemd/system/vmselect.service > /dev/null <<'EOF'
    [Unit]
    Description=vmselect — VictoriaMetrics cluster query
    After=network-online.target

    [Service] Type=simple User=victoriametrics Group=victoriametrics ExecStart=/usr/local/bin/vmselect \ -storageNode=storage-1.internal:8401,storage-2.internal:8401 \ -dedup.minScrapeInterval=15s \ -httpListenAddr=:8481

    Restart=on-failure LimitNOFILE=1048576

    [Install] WantedBy=multi-user.target EOF

    Enable all three on their respective hosts:

    bash
    sudo systemctl daemon-reload
    sudo systemctl enable --now vmstorage   # on storage hosts
    sudo systemctl enable --now vminsert    # on router hosts
    sudo systemctl enable --now vmselect    # on router hosts

    Point vmagent and Grafana at the Cluster

    vmagent now writes to vminsert:

    text
    -remoteWrite.url=http://vminsert.internal:8480/insert/0/prometheus/api/v1/write

    Grafana queries vmselect (note the tenant-prefixed path — use 0 for single-tenant):

    text
    http://vmselect.internal:8481/select/0/prometheus

    The 0 in those paths is the tenant ID. vmcluster is multi-tenant by design: each tenant gets an isolated namespace with no cross-tenant query access.

    Replication Semantics

    With -replicationFactor=2, vminsert writes every sample to 2 storage nodes and vmselect deduplicates on read. You can lose one storage node without losing data or serving partial queries (vmselect sets isPartial=false as long as every shard has at least one replica available). For stricter durability, set -replicationFactor=3 and run three storage nodes.

    Full cluster documentation: docs.victoriametrics.com/Cluster-VictoriaMetrics.html.

    Performance Tuning

    Retention and Disk Planning

    -retentionPeriod=N accepts values like 30d, 6 (months), or 2y. Disk usage scales roughly linearly with active time series and retention. A good back-of-envelope formula for vmsingle:

    text
    bytes_on_disk = active_series  samples_per_day  retention_days * 0.4

    Where 0.4 bytes/sample is a typical VictoriaMetrics compression ratio. A fleet with 500K active series and a 15s scrape interval (5,760 samples/series/day) at 90-day retention gives roughly 104 GB.

    Memory Tuning

    VictoriaMetrics caches index data in RAM. Control memory ceiling with:

    text
    -memory.allowedPercent=60        # default 60% of system RAM
    -memory.allowedBytes=8GB         # absolute cap

    On a 12 GB VPS running vmsingle plus vmagent and vmalert, -memory.allowedPercent=50 leaves room for the neighbors.

    Cardinality Control with streaming aggregation

    Runaway label cardinality (think UUIDs in labels) is the one workload that can still OOM VictoriaMetrics. Use vmagent's streaming aggregation to pre-aggregate at scrape time:

    yaml
    # /etc/vmagent/aggregation.yml
    
    • match: 'http_requests_total'
    interval: 1m outputs: ['total', 'count_series'] by: ['service', 'status']

    Then add -streamAggr.config=/etc/vmagent/aggregation.yml to the vmagent flags. The high-cardinality raw metric is collapsed before it ever reaches storage.

    Index and Query Caches

    The -search.maxConcurrentRequests and -search.maxQueryDuration flags prevent a runaway Grafana dashboard from starving ingestion:

    text
    -search.maxConcurrentRequests=16
    -search.maxQueryDuration=30s

    Deduplication

    In a cluster with replicationFactor > 1, or when two Prometheus servers remote_write the same metrics, set -dedup.minScrapeInterval=15s on vmsingle (or vmselect in cluster mode) to drop duplicate samples during queries.

    Troubleshooting

    ProblemCauseSolution
    victoria-metrics: bind: address already in use on :8428Another process has the portsudo lsof -i :8428 and stop/reconfigure the conflicting service
    Prometheus remote_write fails with context deadline exceededVM endpoint unreachable or overloadedCheck firewall from Prom host; raise queue_config.max_shards in Prometheus
    Dashboards stop updating but service is "running"vmagent queue directory fullCheck /var/lib/vmagent free space; raise -remoteWrite.maxDiskUsagePerURL=10GB
    Alerts not firing-notifier.url missing or Alertmanager downcurl http://localhost:8880/api/v1/alerts to inspect vmalert state
    High memory usage, occasional OOMCardinality explosionInspect /api/v1/status/tsdb for top label pairs; apply streaming aggregation
    vmcluster query returns isPartial: trueOne or more vmstorage nodes unreachablesystemctl status vmstorage on each storage host; check network between vmselect and vmstorage
    Disk fills faster than expectedRetention too high or cardinality growingInspect vm_data_size_bytes; reduce -retentionPeriod or aggregate
    Grafana queries time outExpensive MetricsQL or long rangeAdd recording rules via vmalert; set -search.maxQueryDuration

    Viewing Logs

    bash
    sudo journalctl -u victoriametrics -f
    sudo journalctl -u vmagent -f
    sudo journalctl -u vmalert -f

    For cluster components:

    bash
    sudo journalctl -u vmstorage -u vminsert -u vmselect -f

    Useful Introspection Endpoints

    • GET /api/v1/status/tsdb — top label pairs and cardinality breakdown
    • GET /api/v1/status/active_queries — currently running queries
    • GET /metrics — self-monitoring metrics (scrape into VM itself)
    • GET /flags — effective runtime flags

    FAQ

    Is VictoriaMetrics really a drop-in replacement for Prometheus?

    For storage, querying, and data ingestion, yes — it speaks the Prometheus remote_write protocol, exposes the full Prometheus HTTP query API (/api/v1/query, /api/v1/query_range, /api/v1/label/*), and evaluates PromQL without modification. Where it differs is scraping (handled by vmagent instead of Prometheus's built-in scraper) and alerting (handled by vmalert or Alertmanager directly). Every Grafana dashboard built for Prometheus works against VictoriaMetrics unchanged, and every exporter (node_exporter, blackbox_exporter, postgres_exporter, kube-state-metrics, etc.) works with vmagent as the scraper.

    When should I choose vmsingle vs vmcluster?

    Start with vmsingle. A single well-sized VPS (8-16 GB RAM, NVMe disk) easily handles 1-2 million active time series and 100k samples per second — enough for most mid-sized fleets. Move to vmcluster when you need: (1) native replication for HA, (2) multi-tenancy to isolate customer workloads, (3) horizontal scale beyond a single node's RAM ceiling, or (4) independent scaling of ingestion versus query workloads. The migration path is gentle: you can export from vmsingle and re-ingest into vmcluster with zero downtime on the read side if you keep vmsingle running during the cutover.

    How does VictoriaMetrics compare to InfluxDB, TimescaleDB, and Thanos?

    Compared to InfluxDB, VictoriaMetrics is purpose-built for Prometheus ecosystem integration and typically ingests more samples per CPU core with smaller disk footprint; InfluxDB has broader downsampling and a first-class SQL interface (Flux/InfluxQL). See our InfluxDB install guide for the InfluxDB side. Compared to TimescaleDB, VictoriaMetrics skips the full relational model in favor of specialized metric operations, trading SQL joins for 5-10x better ingestion throughput. Compared to Thanos/Cortex/Mimir, VictoriaMetrics is dramatically simpler to operate (no Kafka, no object storage mandatory, no complex query sharding), and benchmarks consistently show better query latency under high cardinality — at the cost of some features like full downsampling tiers and object-storage backed infinite retention.

    Can I run VictoriaMetrics alongside an existing Prometheus setup?

    Absolutely, and this is the recommended migration path. Keep Prometheus scraping and alerting as-is, add a remote_write block pointing at VictoriaMetrics, then gradually (a) shorten Prometheus's local retention to save disk, (b) move long-range Grafana queries to the VictoriaMetrics data source, and finally (c) replace Prometheus with vmagent once you trust the new stack. There is no flag day — both systems store the same metrics with the same label semantics.

    Does VictoriaMetrics support downsampling?

    The open-source version does not do automatic downsampling in the storage engine — instead, use vmalert recording rules to compute 5-minute or 1-hour rollups and query those recording-rule series from dashboards that span long time ranges. The Enterprise edition adds built-in downsampling tiers. For most fleets, recording rules plus MetricsQL's rollup_* functions deliver equivalent practical benefit.

    What's the biggest operational pitfall to watch for?

    Label cardinality. Any label whose value set is unbounded (user IDs, request IDs, UUIDs, full URL paths with query strings) will inflate the index and eventually push memory usage past healthy limits. Monitor vm_cache_entries{type="storage/tsid"} and the /api/v1/status/tsdb endpoint, and apply vmagent's streaming aggregation or relabel_config to drop or collapse high-cardinality labels before they reach storage.

    Next Steps

    Now that VictoriaMetrics is running on your VPS, here are recommended next steps:

    • Add exporters to round out your monitoring — Deploy node_exporter on every host, blackbox_exporter for synthetic checks, and postgres_exporter / mysqld_exporter if you run databases. vmagent scrapes them exactly like Prometheus does.
    • Install Alertmanager — Pair vmalert with Alertmanager for deduplication, routing (Slack, PagerDuty, email), and silencing.
    • Build Grafana dashboards — Import community dashboards from grafana.com/grafana/dashboards/ (IDs 1860, 11074, and 10826 are popular starters). See our Grafana install guide if you have not set it up yet.
    • Migrate from InfluxDB or Prometheus — Use vmctl (bundled with the cluster archive) to import historical data from Prometheus snapshots, InfluxDB, or OpenTSDB.
    • Harden with TLS and auth — Put Nginx in front of :8428, terminate TLS with Let's Encrypt, and add Basic Auth or mTLS for external access. The same pattern applies to vmagent, vmalert, and vmselect.
    • Compare to Prometheus natively — Our Prometheus install guide walks through the reference setup so you can benchmark the two side by side on the same VPS.
    • Explore the official docs — The full documentation at docs.victoriametrics.com covers advanced topics like backups with vmbackup/vmrestore, multi-tenancy, streaming aggregation recipes, and the Kubernetes Operator.

    Need a VPS sized right for VictoriaMetrics?
    >
    Our CloudCore Professional plan — 6 vCPU, 12 GB RAM, 100 GB NVMe SSD at EUR 19.99/month — comfortably hosts vmsingle + vmagent + vmalert + Grafana + Alertmanager for a mid-size fleet, with headroom for 30-90 days of retention. Need more? Our larger plans scale smoothly into vmcluster territory.
    >
    Launch your CloudCore Professional VPS now and have VictoriaMetrics ingesting metrics within the hour.

    Was this article helpful?

    ← Back to Install GuidesBrowse all categories →

    Still have questions?

    Contact Support →Submit a Ticket