VMCluster
pg addon install vmcluster runs VictoriaMetrics cluster edition — three components each in its own container from the official docker.io/victoriametrics/{vminsert,vmselect,vmstorage}:v1.154.1-cluster images. Unlike the single-node victoriametrics addon (one container, one port), this manages up to three containers with three separate images and five ports, supporting cross-host deployment and horizontal scaling.
Architecture:
| Component | Role | HTTP Port | Internal TCP |
|---|---|---|---|
| vminsert | Ingestion — shards writes across all vmstorage nodes by metric hash | 8480 | Dials vmstorage:InternalInsertPort |
| vmselect | Queries — merges results from all vmstorage nodes | 8481 | Dials vmstorage:InternalSelectPort |
| vmstorage | Data storage (sharded, replicable) | 8482 | Listens on InternalInsertPort + InternalSelectPort |
There is NO web login/password. Like the single-node VictoriaMetrics, the cluster edition ships no authentication at all. Its HTTP API runs arbitrary MetricsQL (a superset of PromQL), so remote-exposed instances are guarded only by the network boundary — your firewall, or
--listen 127.0.0.1for loopback. Treat it like an unauthenticated read/write console.
Platform: Linux only. VMCluster requires host networking for the internal TCP ports between components. On macOS, installation is refused with a clear error.
Deployment Models
Model 1 — Converged single-host (default)
All three components on one host, analogous to BeeGFS v1:
Model 2 — Cross-host distribution
Model 3 — Horizontal scaling with replication
Parameters
| Flag | Default | Description |
|---|---|---|
--name |
vmc |
Instance name (map key) |
--roles |
insert,select,storage |
Comma-separated roles this host runs (subset for cross-host) |
--storage-node |
auto-derived | vmstorage address (repeatable; format host:insertPort:selectPort). Lists ALL vmstorage nodes for sharding/replication. Omit for converged single-host |
--insert-port |
auto (base 8480) | vminsert HTTP port |
--select-port |
auto (base 8481) | vmselect HTTP port |
--storage-port |
auto (base 8482) | vmstorage HTTP port |
--internal-insert-port |
auto (base 8483) | vmstorage TCP port for vminsert protocol |
--internal-select-port |
auto (base 8484) | vmstorage TCP port for vmselect protocol |
--listen |
0.0.0.0 |
Bind address — defaults to every interface; use 127.0.0.1 for loopback-only |
--retention-months |
1 |
Data retention in months (only for vmstorage role) |
--replication-factor |
1 |
How many vmstorage nodes each write goes to (vminsert flag) |
--insert-image |
docker.io/victoriametrics/vminsert:v1.154.1-cluster |
vminsert image override |
--select-image |
docker.io/victoriametrics/vmselect:v1.154.1-cluster |
vmselect image override |
--storage-image |
docker.io/victoriametrics/vmstorage:v1.154.1-cluster |
vmstorage image override |
--insert-extra-arg |
— | Extra CLI flag for vminsert (repeatable) |
--select-extra-arg |
— | Extra CLI flag for vmselect (repeatable) |
--storage-extra-arg |
— | Extra CLI flag for vmstorage (repeatable) |
--data-dir |
auto | vmstorage data directory override |
--force |
false | Recreate even when running |
Install
The command pulls the three images if needed, creates the containers in dependency order (storage → insert → select), and prints the summary:
VMCluster is ready to ingest and query immediately.
Cluster URL Format
Important: The cluster edition uses different URL paths than the single-node VictoriaMetrics. All API endpoints require an <accountID> in the path (use 0 for the default account):
Ingestion via vminsert:
Query via vmselect:
Grafana datasource: Point at vmselect with URL http://<host>:8481/select/0/prometheus/
Prometheus remote_write: Configure remote_write to http://<host>:8480/insert/0/prometheus/api/v1/write
Ports
Each VMCluster instance owns 5 consecutive ports from the vmcluster_start_port pool (default 8480):
+0InsertPort (vminsert HTTP — ingestion endpoint)+1SelectPort (vmselect HTTP — query endpoint)+2StoragePort (vmstorage HTTP — admin/metrics endpoint)+3InternalInsertPort (vmstorage TCP — vminsert dials this)+4InternalSelectPort (vmstorage TCP — vmselect dials this)
The consecutive allocation matters because --storage-node references the internal TCP ports explicitly, so the block must stay together. 8480 shares no number with VictoriaMetrics (8428), Prometheus (9090), Grafana (3000), or the rest.
Configuration
There is no config file — everything is passed as CLI flags to the three binaries. storage_nodes is the cross-host topology; empty means auto-derived single-node.
Adding storage nodes
VictoriaMetrics cluster has no dynamic discovery — the -storageNode list is baked into the vminsert/vmselect containers at startup. Adding a vmstorage node requires a brief maintenance window to recreate the access-layer containers (not a hot reload). Existing vmstorage data is unaffected.
Maintenance impact: rebuilding vminsert/vmselect causes a few-second write interruption. Plan this during a low-traffic window if write continuity is critical. Historical data in vmstorage remains available throughout — only ingestion is briefly interrupted.
Steps
- Create the new vmstorage on the target host:
- Recreate vminsert + vmselect on the access-layer host, appending the new
--storage-node:
--force drops and recreates the vminsert/vmselect containers. There is a few-second write interruption; existing vmstorage data is untouched (only the access-layer containers are replaced).
Data distribution after adding a node
- Old data stays on the original vmstorage nodes (no automatic rebalance).
- New writes are re-sharded across all nodes (old + new) by metric hash.
- vmselect merges from all nodes, so queries see both old and new data seamlessly.
VictoriaMetrics cluster does not migrate existing data to a newly added node. For most monitoring workloads this is acceptable — time series are continuously written, and after a few hours the new node holds enough data for queries to be balanced. If even distribution is required, export and re-import the old data (/api/v1/export → /api/v1/import).
Removing storage nodes
Reverse the process: recreate vminsert/vmselect without the departing node’s --storage-node, then pg addon remove vmcluster on the departing host. Data on the removed vmstorage becomes inaccessible to queries — export it first if it needs to be preserved.
Start and stop
Containers run with podman’s unless-stopped restart policy, so they come back automatically after a host reboot.
Autostart on boot
Boot is cluster-granular: each host starts only the roles it runs, in dependency order (storage → insert → select), bringing up existing containers and recreating only what is missing — it never recreates running services. Run the command on every host in a cross-host deployment. See Autostart for the full mechanism.
Remove
Only vmstorage has persistent data; vminsert and vmselect are stateless and leave nothing behind.
Logs
Known limitations
- No authentication. The cluster edition’s API runs arbitrary MetricsQL; the only protection for a
0.0.0.0bind is the network boundary. - Linux only. Host networking is required for the internal TCP ports between components.
- No automatic load balancing. For multiple vminsert/vmselect instances, put HAProxy or nginx in front manually.
- No TLS. Use the nginx addon for TLS termination if needed.
- pgcli does not validate
--extra-argvalues. A bad flag surfaces only in the container logs on startup.