Skip to main content

Configuration

Soltix uses a YAML configuration file for both the Router and Storage services. Configuration is loaded via Viper with support for file-based config, default values, and environment variable overrides.

Loading Order

Both services accept a -config flag to specify the config file path:

./router -config ./configs/config.yaml
./storage -config ./configs/config.yaml

If no -config flag is provided, Soltix searches for config.yaml in the following locations (in order):

  1. Current working directory (./)
  2. ./configs/
  3. ./config/
  4. /etc/soltix/

If no config file is found, the service starts with default values.

Environment Variable Overrides

All config values can be overridden via environment variables with the SOLTIX_ prefix. Nested keys use _ as separator:

export SOLTIX_SERVER_HTTP_PORT=5555
export SOLTIX_STORAGE_NODE_ID=node-02
export SOLTIX_QUEUE_TYPE=redis
export SOLTIX_LOGGING_LEVEL=debug

Full Configuration Reference

server

Network settings for HTTP and gRPC servers.

server:
host: 0.0.0.0
http_port: 5555
grpc_port: 5556
grpc_host: "localhost"
KeyTypeDefaultDescription
hoststring0.0.0.0Bind address for both HTTP and gRPC servers
http_portint5555HTTP API port (1-65535)
grpc_portint5556gRPC inter-service port (1-65535, must differ from http_port)
grpc_hoststring""Advertise address for gRPC service discovery. Used as fallback when host is 0.0.0.0 and auto IP detection fails. Set this in Docker/VM environments with complex networking

storage

Storage engine settings. Used by the Storage service only.

storage:
node_id: storage-node-01
data_dir: ./data
timezone: "UTC"
memory_store:
max_age: 2h
max_size: 100000
flush:
interval: 5m
max_records: 50000
max_wal_segments: 10
multipart:
max_rows_per_part: 100000
max_part_size: 67108864
min_rows_per_part: 1000
max_devices_per_group: 50
sync:
enabled: true
startup_sync: true
startup_timeout: 5m
sync_batch_size: 1000
max_concurrent_syncs: 5
anti_entropy:
enabled: true
interval: 1h
batch_size: 10000

storage (root)

KeyTypeDefaultRequiredDescription
node_idstringstorage-default-nodeYesUnique identifier for this storage node. Must be unique across the cluster
data_dirstring./dataYesRoot directory for all persistent data (WAL, V6 part files, aggregations)
timezonestringUTCNoTimezone for data storage, sharding, and file organization. Supports IANA format (Asia/Tokyo, America/New_York) or offset format (+09:00, -05:00)

storage.memory_store

Hot data cache for recent writes. Data within max_age is kept in memory for fast reads.

KeyTypeDefaultDescription
max_ageduration2hHow long to keep data in memory. Data older than this is only available on disk
max_sizeint100000Maximum number of records in memory across all 64 shards

storage.flush

Controls when data is flushed from WAL to disk (V6 columnar files).

KeyTypeDefaultDescription
intervalduration5mTime-based flush trigger interval
max_recordsint50000Flush when record count in WAL exceeds this threshold
max_wal_segmentsint10Flush when WAL segment count exceeds this threshold

storage.multipart

V6 columnar part file settings. Controls how data is split across part files.

KeyTypeDefaultDescription
max_rows_per_partint100000Primary split criterion — create new part file when row count exceeds this
max_part_sizeint6467108864 (64 MB)Safety limit — split if part file exceeds this size in bytes
min_rows_per_partint1000Don't split if part has fewer rows than this
max_devices_per_groupint50Maximum devices per device group (DG). New DG created when exceeded

storage.sync

Replica synchronization settings for multi-node deployments.

KeyTypeDefaultDescription
enabledbooltrueEnable sync functionality
startup_syncbooltrueRecover missed data from replicas on node startup
startup_timeoutduration5mMaximum time to wait for startup sync to complete
sync_batch_sizeint1000Batch size when writing synced data points
max_concurrent_syncsint5Maximum number of concurrent shard syncs during startup

storage.sync.anti_entropy

Background consistency checker that compares checksums between replicas.

KeyTypeDefaultDescription
enabledbooltrueEnable anti-entropy background process
intervalduration1hHow often to run checksum comparison
batch_sizeint10000Number of data points per checksum batch

etcd

etcd connection settings. etcd is required for cluster coordination, node registry, and group assignment.

etcd:
endpoints:
- http://localhost:2379
dial_timeout: 5s
username: ""
password: ""
KeyTypeDefaultRequiredDescription
endpointsstring[]["http://localhost:2379"]YesList of etcd server endpoints
dial_timeoutduration5sNoConnection timeout. Must be positive
usernamestring""Noetcd authentication username
passwordstring""Noetcd authentication password

queue

Message queue configuration. Writes flow through the queue from Router to Storage nodes.

queue:
type: "nats"
url: nats://localhost:4222
username: ""
password: ""
KeyTypeDefaultDescription
typestringnatsQueue backend: nats, redis, kafka, or memory
urlstringnats://localhost:4222Server URL (NATS or Redis)
usernamestring""Authentication username (NATS)
passwordstring""Authentication password (NATS)

Redis-specific options

Used when type: "redis":

queue:
type: "redis"
url: localhost:6379
redis_db: 0
redis_stream: "soltix"
redis_group: "soltix-group"
redis_consumer: "soltix-consumer-01"
KeyTypeDefaultDescription
redis_dbint0Redis database number
redis_streamstringsoltixRedis stream name prefix
redis_groupstringsoltix-groupRedis consumer group name
redis_consumerstringhostnameRedis consumer name (unique per node)

Kafka-specific options

Used when type: "kafka":

queue:
type: "kafka"
kafka_brokers: ["localhost:9092"]
kafka_group_id: "soltix-consumers"
KeyTypeDefaultDescription
kafka_brokersstring[]["localhost:9092"]Kafka broker addresses
kafka_group_idstringsoltix-consumersKafka consumer group ID

Memory queue

Used when type: "memory". No additional options. For testing only — data is not persisted and not shared between processes.

coordinator

Sharding and group assignment settings. Used by the Router service.

coordinator:
hash_threshold: 20
vnode_count: 200
replica_factor: 3
total_groups: 256
auto_assigner:
enabled: true
poll_interval: 15s
rebalance_on_join: true
rebalance_threshold: 10
KeyTypeDefaultDescription
hash_thresholdint20Node count threshold to switch from Rendezvous hashing (better distribution for small clusters) to Consistent hashing (O(log N) lookups for large clusters)
vnode_countint200Virtual nodes per physical node when using consistent hashing
replica_factorint3Number of replica nodes per group assignment
total_groupsint256Total number of logical groups for device-based sharding. Devices are mapped via FNV32a(db:collection:device_id) % total_groups

coordinator.auto_assigner

Automatic group-to-node assignment and rebalancing.

KeyTypeDefaultDescription
enabledbooltrueEnable automatic group assignment
poll_intervalduration15sHow often to check etcd for node changes
rebalance_on_joinbooltrueRebalance groups when a new node joins the cluster
rebalance_thresholdint10Maximum group count difference between nodes before triggering rebalance

replication

Data replication settings.

replication:
factor: 3
strategy: async
min_replicas_for_write: 1
KeyTypeDefaultDescription
factorint3Number of replicas per data shard (1-10)
strategystringasyncReplication strategy: async (non-blocking) or sync (wait for all replicas)
min_replicas_for_writeint1Minimum replicas that must acknowledge a write. Must be between 1 and factor

auth

API key authentication. Used by the Router service.

auth:
enabled: true
api_keys:
- "your-api-key-with-at-least-32-characters"
KeyTypeDefaultDescription
enabledboolfalseEnable API key authentication. When false, all requests are allowed
api_keysstring[][]List of valid API keys. Each key must be at least 32 characters

When enabled, clients must pass the API key via one of these headers:

  • X-API-Key: <key>
  • Authorization: Bearer <key>
  • Authorization: ApiKey <key>

logging

Logging configuration.

logging:
level: info
format: json
output_path: stdout
time_format: RFC3339
KeyTypeDefaultDescription
levelstringinfoLog level: debug, info, warn, error
formatstringjsonOutput format: json or console
output_pathstringstdoutOutput destination: stdout, stderr, or a file path
time_formatstringRFC3339Timestamp format in log output

Example Configurations

Minimal (single node, development)

server:
http_port: 5555
grpc_port: 5556

storage:
node_id: dev-node
data_dir: ./data

etcd:
endpoints:
- http://localhost:2379

queue:
type: "memory"

auth:
enabled: false

logging:
level: debug
format: console

Production (multi-node with NATS)

server:
host: 0.0.0.0
http_port: 5555
grpc_port: 5556
grpc_host: "192.168.1.100"

storage:
node_id: storage-node-01
data_dir: /var/lib/soltix/data
timezone: "UTC"
memory_store:
max_age: 24h
max_size: 100000
flush:
interval: 5m
max_records: 50000
max_wal_segments: 10
multipart:
max_rows_per_part: 100000
max_part_size: 67108864
min_rows_per_part: 1000
max_devices_per_group: 50
sync:
enabled: true
startup_sync: true
startup_timeout: 5m
max_concurrent_syncs: 5
anti_entropy:
enabled: true
interval: 1h

etcd:
endpoints:
- http://etcd-1:2379
- http://etcd-2:2379
- http://etcd-3:2379
dial_timeout: 5s

queue:
type: "nats"
url: nats://nats:4222

coordinator:
total_groups: 256
replica_factor: 3
auto_assigner:
enabled: true
poll_interval: 15s
rebalance_on_join: true

replication:
factor: 3
strategy: async
min_replicas_for_write: 1

auth:
enabled: true
api_keys:
- "your-production-api-key-at-least-32-characters-long"

logging:
level: info
format: json
output_path: /var/log/soltix/soltix.log

Docker

server:
host: 0.0.0.0
http_port: 5555
grpc_port: 5556
grpc_host: "storage"

storage:
node_id: storage-node-01
data_dir: /app/data
timezone: "UTC"

etcd:
endpoints:
- http://etcd:2379

queue:
type: "nats"
url: nats://nats:4222

In Docker, use container/service names (etcd, nats, storage) instead of localhost.

With Redis Queue

queue:
type: "redis"
url: localhost:6379
redis_db: 0
redis_stream: "soltix"
redis_group: "soltix-group"
redis_consumer: "consumer-01"

With Kafka Queue

queue:
type: "kafka"
kafka_brokers:
- "kafka-1:9092"
- "kafka-2:9092"
- "kafka-3:9092"
kafka_group_id: "soltix-consumers"

Validation Rules

The following validation rules are enforced at startup:

SectionRule
server.http_portMust be 1-65535
server.grpc_portMust be 1-65535, must differ from http_port
storage.data_dirRequired, cannot be empty
storage.memory_store.max_ageMust be positive
storage.memory_store.max_sizeMust be positive
etcd.endpointsAt least one endpoint required
etcd.dial_timeoutMust be positive
replication.factorMust be 1-10
replication.strategyMust be sync or async
replication.min_replicas_for_writeMust be between 1 and replication.factor
logging.levelMust be debug, info, warn, or error
logging.formatMust be json or console

If validation fails, the service exits with an error message indicating the invalid field.