Reference
This reference covers the configuration files and fields available for self-managed Director deployments. Managed Directors receive their configuration from the DataStream platform automatically; the fields documented here are relevant when you manage Director infrastructure directly.
For Director concepts and GUI-based setup, see Overview. For installation procedures, see Deployment.
Configuration Files
A Director reads two categories of configuration at startup:
| File | Location | Purpose |
|---|---|---|
| Service configuration | vmetric.yml in the Director working directory | Core service settings (identity, network, queue, processing defaults) |
| Environment configuration | config/environments/*.yml | Topology, clustering, ACL, and TLS |
Supported formats: YAML (.yml / .yaml), TOML (.toml), and VMF (.vmf). Maximum file size: 1 MB.
Config file lookup order (first match wins):
vmetric.tomlvmetric.ymlvmetric.yaml
When the virtualmetric=debug environment variable is set, the service loads vmetric-local.yml (or .toml / .yaml) instead of the standard file. This is intended for local development and troubleshooting only -- do not use in production.
Service Configuration (vmetric.yml)
Director Identity
| Field | YAML Path | Type | Default | Description |
|---|---|---|---|---|
| ID | director.id | int64 | -- | Unique Director instance identifier |
| Status | director.status | bool | true | Enable or disable the Director service |
| Stream | director.stream | string | -- | NATS stream name for Director replies |
Network
| Field | YAML Path | Type | Default | Description |
|---|---|---|---|---|
| Address | listen.address | string | 0.0.0.0 | Bind address for all listeners |
| External Address | listen.external_address | string | -- | Advertised address for remote connections (comma-separated for multiple) |
| Port | listen.port | int | 8890 | Main collector listening port |
| WebSocket Port | listen.ws_port | int | 9080 | VMMQ WebSocket port |
| HTTP Config Port | listen.httpconfigport | int | 80 / 443 | HTTP configuration server port |
Queue
| Field | YAML Path | Type | Default | Description |
|---|---|---|---|---|
| Limit | queue.limit | int | 172800 (48 h) | Queue size limit in seconds |
| Parallelism | queue.parallelism | int | CPU count | Queue processing parallelism |
| Non-Existing Target Limit | queue.non_existing_target_limit | int | 86400 (24 h) | TTL for queued data to non-existing targets (seconds) |
| Cleanup Interval | queue.cleanup_interval | int | 900 (15 min) | Cleanup interval for non-existing target queues (seconds) |
| DeQueue Interval | queue.dequeue_interval | int | 1 | DeQueue processing interval in seconds |
Debug and Logging
| Field | YAML Path | Type | Default | Description |
|---|---|---|---|---|
| Level | debug.level | int | 0 | Debug verbosity: 0 = off, 1--3 = increasing detail |
| Console Status | debug.console.status | bool | false | Enable console debug output |
| Log Status | debug.log.status | bool | false | Enable file-based debug logging |
| Remote | debug.remote | bool | false | Enable remote debug mode (disables device tasks when true) |
Fleet
Fleet settings control how a Director connects to the DataStream cloud platform. Self-managed Directors that operate independently (no fleet connection) set self_managed: true and omit the fleet block.
| Field | YAML Path | Type | Default | Description |
|---|---|---|---|---|
| Self-Managed | self_managed | bool | -- | If true, Director runs independently without fleet connection |
| Fleet Type | fleet.type | string | -- | Connection type (e.g., httpclient) |
| Fleet Instance | fleet.instance | string | -- | Fleet environment instance name |
| Fleet Address | fleet.address | string | -- | Fleet server WebSocket URL |
| Fleet Token | fleet.token | string | -- | Authentication token for fleet |
Data Processing Defaults
These defaults apply to all data processing unless overridden at the device or target level.
| Field | YAML Path | Type | Default | Description |
|---|---|---|---|---|
| Compression | compression | bool | true | Enable data compression |
| Compression Level | compression_level | string | -- | Compression level (algorithm-specific) |
| Reuse | reuse | bool | true | Enable connection reuse |
| Normalization | normalization | bool | true | Enable data normalization |
| Smart Data Engine | smart_data_engine | bool | true | Enable SDxL processing |
| No Buffer | no_buffer | bool | false | Disable buffering |
| Batch Size | batch_size | int64 | 10000 | Read batch size |
| Write Batch Size | write_batch_size | int64 | 1000 | Write batch size |
| Workers | workers | int | CPU count | Worker count |
| Chunk Size | chunk_size | int | 4194304 (4 MB) | Data chunk size in bytes |
| Min Chunk Count | min_chunk_count | int | 10 | Minimum chunk count |
| Stats Enabled | stats_enabled | bool | false | Enable per-device, per-route, and per-target metrics collection. Fleet-managed Directors override this to true automatically. |
| Stats Drop On Full | stats_drop_on_full | bool | true | When the stats channel buffer is full, drop new metrics rather than blocking the record producer. |
| Disable Direct | disable_direct | bool | false | Disable the in-process listener-to-target fast path. When false, the direct path engages automatically when eligible. |
Collector Resource Management
Controls resource allocation and scheduling for device collectors.
| Field | YAML Path | Type | Default | Description |
|---|---|---|---|---|
| Retry Interval | retry_interval | int | 30 | Device retry delay in seconds |
| Start Delay | start_delay | int | 1 | Collector startup delay in seconds |
| Windows Start | windows_start | int | 524288000 (500 MB) | Memory threshold for Windows collectors (bytes) |
| Windows Start Buffer | windows_start_buffer | bool | -- | Buffer mode for Windows collectors |
| Monitor Interval | monitor_interval | int | 30 | Monitor interval in seconds |
| Flush Interval | flush_interval | int | 1 | Log flush interval in seconds |
| Modules | modules | bool | true | Enable or disable module loading |
Profiler
| Field | YAML Path | Type | Default | Description |
|---|---|---|---|---|
| Profile Port | profiler.director_profile_port | int | 6061 | pprof profiler port |
| Timeout | profiler.timeout | int | 60 | Profiler and metrics collection timeout in seconds |
Load Balancer
| Field | YAML Path | Type | Default | Description |
|---|---|---|---|---|
| Mode | loadbalancer.mode | string | -- | Set to dynamic for dynamic load balancing across cluster nodes |
Persistent Storage
Controls whether pipeline data survives a restart, and how far upstream that durability extends. The two flags combine into four modes:
persistent_storage.status | crash_resistance | Effect |
|---|---|---|
false (default, standalone) | forced false | In-memory VMFL/VMF and JetStream MemoryStorage. Maximum throughput; records buffered in process memory are lost on a crash. |
true | false | JetStream FileStorage plus the NATS Object Store for payloads. VMFL/VMF writers stay in-memory; durability is provided by NATS. |
true | true | Enterprise: local VMFL/VMF queue writers also go to disk, flushing each record to the OS page cache -- process-crash durable end-to-end. |
false | true | Ignored -- crash_resistance is forced false and the mode collapses to the first row. |
| Field | YAML Path | Type | Default | Description |
|---|---|---|---|---|
| Status | persistent_storage.status | bool | false | Enable the durable NATS JetStream pipeline layer (JetStream FileStorage + NATS Object Store). Defaults to true on fleet-managed Directors. |
| Crash Resistance | persistent_storage.crash_resistance | bool | false | Also write the local VMFL/VMF queue files to disk, flushing each record to the OS page cache so the upstream pipeline hops survive a process crash (SIGKILL, OOM, panic). Enterprise deployments; only effective when persistent_storage.status: true (forced false otherwise). |
crash_resistance targets process-crash durability, not power loss. With persistent_storage.status: true, power-loss durability is provided by NATS -- best-effort on a single node (default 2-minute sync interval) or per-write via RAFT quorum on a cluster. For power-loss-sensitive workloads, run a cluster.
In clustered or environment-file deployments, place the persistent_storage block -- including its nested payload and pipeline_bus -- under a node's or the cluster's properties: block rather than at the top level of vmetric.yml (see the persistent-storage examples at the end of this page). These settings must be uniform across all nodes of a cluster.
Payload
Configures the payload backend that carries log record bytes between pipeline stages. The payload and pipeline_bus blocks nest inside persistent_storage; the full key paths are persistent_storage.payload.* and persistent_storage.pipeline_bus.*.
| Field | YAML Path | Type | Default | Description |
|---|---|---|---|---|
| Type | persistent_storage.payload.type | string | "" | Payload backend: inline (bytes carried in the pipeline message), object_store (NATS Object Store), memory (in-process store), or "" (automatic — memory when persistent storage is off, object_store when on). |
| Max Size | persistent_storage.payload.max_size | string | "" | Maximum payload size per record. Accepts a plain integer (bytes) or a size suffix such as 1mb or 512kb. When the payload type is inline defaults to 1 MB to fit within Kafka and Event Hubs message limits; unlimited for other backends. |
Pipeline Bus
Configures the transport that moves stage-to-stage pipeline notifications between the ingester, router, and sender workers.
| Field | YAML Path | Type | Default | Description |
|---|---|---|---|---|
| Type | persistent_storage.pipeline_bus.type | string | nats | Stage-to-stage transport: nats (embedded VMMQ, default) or kafka (external Kafka broker including Azure Event Hubs' Kafka endpoint). |
| Address | persistent_storage.pipeline_bus.address | string | -- | Comma-separated Kafka broker addresses. Required when the pipeline bus type is kafka. |
| Topic Prefix | persistent_storage.pipeline_bus.topic_prefix | string | vm-pipeline | Prefix for stage topics. Topics are named <prefix>.<stage> (e.g., vm-pipeline.sender). |
| Algorithm | persistent_storage.pipeline_bus.algorithm | string | -- | Kafka SASL algorithm: plain, scram-sha-256, scram-sha-512, or gssapi. |
| Username | persistent_storage.pipeline_bus.username | string | -- | Kafka SASL username. |
| Password | persistent_storage.pipeline_bus.password | string | -- | Kafka SASL password. |
| TLS Status | persistent_storage.pipeline_bus.tls.status | bool | false | Enable TLS for the Kafka broker connection. |
pipeline_bus.type: kafka requires payload.type: inline. If payload.type is not inline, the Director logs a warning and reverts to the nats transport.
Environment Configuration
Environment files define Director topology, clustering, and access control. Located in config/environments/. Files containing .example. or .sample. in their name are templates only and are not loaded by the system.
Standalone Director
Minimal configuration for a single Director instance. The node name must match the director.id from vmetric.yml.
environments:
- name: "1"
status: true
nodes:
- name: "1"
status: true
Clustered Director
Clustered configurations define a cluster with multiple nodes for high availability. See Clusters for operational details.
cluster: "{cluster-id}"
environments:
- name: "{cluster-id}"
description: "Production Cluster"
status: true
clusters:
- name: "{cluster-id}"
description: "Primary Cluster"
status: true
type: director
properties:
address: "10.0.0.1"
port: 6222
authentication:
username: ""
password: ""
token: ""
tls:
status: false
cert_name: "cert.pem"
key_name: "key.pem"
ca_name: ""
verify: false
nodes:
- name: "{node-1-id}"
status: true
properties:
address: "10.0.0.1"
port: 4222
cluster:
address: "10.0.0.1"
port: 6222
authentication:
token: ""
tls:
status: false
ACL
ACL rules can be applied at the cluster or node level within environment files.
| Field | YAML Path | Type | Default | Description |
|---|---|---|---|---|
| Allowed IPs | acl.allowed_ips | []string | -- | IP allowlist (individual IPs, ranges "ip1 - ip2", or CIDR notation) |
| Access Tokens | acl.allowed_tokens | []string | -- | Valid access tokens for API authentication |
| Rate Limit Max | acl.rate_limit_max_requests | int | 100 | Maximum requests per rate limit window |
| Rate Limit Window | acl.rate_limit_window | int | 60 | Rate limit window in seconds |
| Update Interval | acl.update_interval | int | 20 | ACL configuration refresh interval in seconds |
TLS
TLS settings for inter-node and cluster communication.
| Field | YAML Path | Type | Default | Description |
|---|---|---|---|---|
| Status | tls.status | bool | false | Enable TLS |
| Cert Name | tls.cert_name | string | cert.pem | TLS certificate filename |
| Key Name | tls.key_name | string | key.pem | TLS key filename |
| CA Name | tls.ca_name | string | -- | CA certificate filename |
| Verify | tls.verify | bool | false | Enable certificate verification |
Node Properties
| Field | YAML Path | Type | Default | Description |
|---|---|---|---|---|
| Address | properties.address | string | -- | Node bind address |
| Port | properties.port | int | 4222 | Node NATS port |
| Cluster Address | properties.cluster.address | string | -- | Cluster communication address |
| Cluster Port | properties.cluster.port | int | 6222 | Cluster communication port |
Health Check Configuration
Health checks monitor device collector resources. A resource must exceed its threshold for the configured number of consecutive iterations before action is taken.
Check Toggles
| Field | YAML Path | Type | Default | Description |
|---|---|---|---|---|
| Check CPU Usage | health.check_cpu_usage | bool | false | Monitor CPU usage |
| Check Memory Usage | health.check_memory_usage | bool | false | Monitor memory usage |
| Check Log File Usage | health.check_log_file_usage | bool | true | Monitor log file sizes |
| Check TMP Usage | health.check_tmp_usage | bool | false | Monitor temp directory |
| Check Report Usage | health.check_report_usage | bool | true | Monitor report files |
| Check Simulator Usage | health.check_simulator_usage | bool | true | Monitor simulator |
| Check Hanged Processes | health.check_hanged_processes | bool | true | Detect hung processes |
| Check Stats Usage | health.check_stats_usage | bool | true | Monitor stats collection |
Thresholds
| Field | Default | Description |
|---|---|---|
| CPU Limit | 80% | CPU usage threshold percentage |
| Memory Limit | 1024 MB | Memory usage threshold |
| Max Log Size | 10 MB | Maximum log file size |
| Stats Retention | 24 hours | Stats retention period |
Threshold Iterations
All threshold iteration defaults are 10. A resource must exceed its threshold for this many consecutive check iterations before the health system takes action.
VIP (Virtual IP) Configuration
VIP enables high-availability failover for clustered Directors. Configured within cluster properties in the environment file.
| Field | YAML Path | Type | Default | Description |
|---|---|---|---|---|
| Use VIP | vip.use_vip | bool | false | Enable VIP management |
| Bind VIP | vip.bind_vip | bool | false | Bind VIP on startup |
| VIP Address | vip.vip_address | string | -- | Virtual IP address |
| VIP Netmask | vip.vip_netmask | string | -- | VIP subnet mask |
| VIP Gateway | vip.vip_gateway | string | -- | VIP gateway address |
| VIP Interface | vip.vip_interface | string | -- | Network interface for VIP |
| VIP Monitor Interval | vip.vip_monitor_interval | int | -- | Health check interval in seconds |
| Is NATS Cluster | vip.is_nats_cluster | bool | false | Whether this is a NATS cluster (affects VIP binding logic) |
Environment Variables
| Variable | Value | Effect |
|---|---|---|
virtualmetric | debug | Loads vmetric-local.yml instead of vmetric.yml |
Debug config file lookup order:
{serviceName}-local.toml{serviceName}-local.yml{serviceName}-local.yaml
Internal Timing Constants
These values are hardcoded and not user-configurable. They are documented here for operational awareness.
Manager Intervals
| Constant | Value | Purpose |
|---|---|---|
| Heartbeat Update Interval | 5 s | Device heartbeat publishing frequency |
| Leader Check Interval | 1 s | Leadership election check frequency |
| KV Sync Interval | 5 s | JetStream KV synchronization |
| Config Sync Interval | 1 s | Configuration change polling |
| Heartbeat Check Interval | 15 s | Device health check and node offline threshold |
Cluster Update Intervals
| Constant | Value | Purpose |
|---|---|---|
| Cluster Update Check Interval | 10 s | Poll for pending updates |
| Node Timeout | 30 min | Maximum wait for a single node update |
| Health Check Wait | 30 s | Post-update health check delay |
| Leader Stability | 30 s | Required leader stability before proceeding |
| Command Retry Interval | 30 s | Between retry attempts |
| Max Retries | 3 | Maximum update retries per node |
| Max Offline Retries | 5 | Maximum retries for offline nodes |
Configuration Limits
| Constant | Value | Purpose |
|---|---|---|
| Config File Max Size | 1 MB | Maximum configuration file size |
| Retention Interval | ~3 months | Default data retention period |
Examples
Minimal Standalone Director
vmetric.yml:
director:
id: 1
listen:
address: "0.0.0.0"
port: 8080
debug:
level: 1
console:
status: true
config/environments/env.yml:
environments:
- name: "1"
status: true
nodes:
- name: "1"
status: true
Production Standalone with ACL
vmetric.yml:
director:
id: 1
listen:
address: "0.0.0.0"
external_address: "10.0.1.100"
port: 8890
queue:
limit: 900000000
debug:
level: 1
console:
status: false
log:
status: true
config/environments/env.yml:
environments:
- name: "1"
status: true
nodes:
- name: "1"
status: true
properties:
acl:
allowed_ips:
- "10.0.0.0/24"
- "192.168.1.50"
- "172.16.0.1 - 172.16.0.254"
access_tokens:
- "prod-token-abc123"
rate_limit_max_requests: 200
rate_limit_window: 60
Three-Node HA Cluster with VIP
vmetric.yml (same on all nodes, only director.id differs):
director:
id: 1 # Change to 2, 3 on other nodes
listen:
address: "0.0.0.0"
external_address: "10.0.1.101"
port: 8890
queue:
limit: 900000000
debug:
level: 2
console:
status: true
log:
status: true
loadbalancer:
mode: dynamic
config/environments/cluster.yml:
cluster: "prod-cluster"
environments:
- name: "prod-cluster"
description: "Production HA Cluster"
status: true
clusters:
- name: "prod-cluster"
description: "3-node director cluster"
status: true
type: director
properties:
address: "10.0.1.101"
port: 6222
authentication:
token: "cluster-secret-token"
tls:
status: true
cert_name: "cluster-cert.pem"
key_name: "cluster-key.pem"
ca_name: "ca.pem"
verify: true
acl:
allowed_ips:
- "10.0.0.0/16"
allowed_tokens:
- "api-token-xyz"
rate_limit_max_requests: 500
rate_limit_window: 60
vip:
use_vip: true
bind_vip: true
vip_address: "10.0.1.100"
vip_netmask: "255.255.255.0"
vip_gateway: "10.0.1.1"
vip_interface: "eth0"
vip_monitor_interval: 5
is_nats_cluster: true
update:
mode: auto
method: cron
cron: "0 3 * * 0"
version: "latest"
nodes:
- name: "1"
description: "Node 1 - 10.0.1.101"
status: true
properties:
address: "10.0.1.101"
port: 4222
cluster:
address: "10.0.1.101"
port: 6222
authentication:
token: "cluster-secret-token"
tls:
status: true
cert_name: "cluster-cert.pem"
key_name: "cluster-key.pem"
ca_name: "ca.pem"
verify: true
- name: "2"
description: "Node 2 - 10.0.1.102"
status: true
properties:
address: "10.0.1.102"
port: 4222
cluster:
address: "10.0.1.102"
port: 6222
authentication:
token: "cluster-secret-token"
tls:
status: true
cert_name: "cluster-cert.pem"
key_name: "cluster-key.pem"
ca_name: "ca.pem"
verify: true
- name: "3"
description: "Node 3 - 10.0.1.103"
status: true
properties:
address: "10.0.1.103"
port: 4222
cluster:
address: "10.0.1.103"
port: 6222
authentication:
token: "cluster-secret-token"
tls:
status: true
cert_name: "cluster-cert.pem"
key_name: "cluster-key.pem"
ca_name: "ca.pem"
verify: true
Fleet-Managed Director
vmetric.yml:
self_managed: false
fleet:
type: httpclient
instance: production
address: wss://fleet.virtualmetric.io/ws
token: "fleet-auth-token-abc123"
director:
id: 2028574672450228224
listen:
address: "0.0.0.0"
port: 8890
debug:
level: 1
console:
status: true
Persistent Storage (Embedded NATS)
Durable pipeline on the embedded NATS backend -- the default when no payload or pipeline_bus is set. JetStream switches to FileStorage and payloads move to the NATS Object Store; VMFL/VMF writers stay in-memory. In a cluster, put these settings on the cluster's properties (they must be uniform across all nodes), not per-node.
config/environments/env.yml:
environments:
- name: "1"
status: true
nodes:
- name: "1"
status: true
properties:
persistent_storage:
status: true
For the Enterprise crash-resistant mode, add crash_resistance: true -- the local VMFL/VMF queue writers also go to disk, flushed per record:
persistent_storage:
status: true
crash_resistance: true
External Kafka / Redpanda
Routes the router-to-sender hop over an external Kafka-compatible broker. Requires payload.type: inline -- with any other payload type the bus silently falls back to nats. The topic (vm-pipeline.sender) and consumer group (<director-name>-sender) auto-create where the broker allows it.
config/environments/env.yml:
environments:
- name: "1"
status: true
nodes:
- name: "1"
status: true
properties:
persistent_storage:
status: true
payload:
type: inline
max_size: 512kb
pipeline_bus:
type: kafka
address: "{broker-1}:9092,{broker-2}:9092"
topic_prefix: vm-pipeline
# Optional SASL auth -- omit the block below for a plaintext broker.
# algorithm: plain # plain | scram-sha-256 | scram-sha-512 | gssapi
# username: "{username}"
# password: "{password}"
# tls:
# status: true
The inline payload rides base64-encoded inside the bus message, so max_size caps the raw payload before encoding (~4/3 on the wire). 512kb (~683 KB encoded) stays under a default broker's ~1 MB message.max.bytes; raise it only in step with the broker limit. For crash resistance, add crash_resistance: true under persistent_storage (the shipped example also raises max_size to 1mb).
Azure Event Hubs (Kafka endpoint)
Uses the Event Hubs Kafka endpoint as the pipeline bus -- the durable-broker option for ephemeral deployments (e.g. Azure Container Apps) with no durable local disk, where in-flight data survives a container restart inside the managed broker. SASL PLAIN over TLS on port 9093.
config/environments/env.yml:
environments:
- name: "{director-id}"
status: true
nodes:
- name: "{director-id}"
status: true
properties:
persistent_storage:
status: true
payload:
type: inline
max_size: 512kb
pipeline_bus:
type: kafka
address: "{namespace}.servicebus.windows.net:9093"
topic_prefix: vm-pipeline
algorithm: plain
username: "$ConnectionString"
password: "Endpoint=sb://{namespace}.servicebus.windows.net/;SharedAccessKeyName={policy};SharedAccessKey={key}"
tls:
status: true
Event Hubs does not auto-create topics: pre-create the event hub vm-pipeline.sender and the consumer group <director-name>-sender before starting the Director -- a missing topic drops 100% of pipeline traffic. Keep payload.max_size at or below the namespace tier's message cap (Basic 256 KB, Standard/Premium 1 MB, Dedicated 20 MB), measured on the raw payload before base64. Add crash_resistance: true under persistent_storage for the Enterprise crash-resistant mode.