vike
ReferenceSettings files

config.toml

Deployment settings — store roots, log and journal directories, and the three listen or dial addresses — each with its environment variable and whether a running daemon can apply it without a restart.

crates/vike-config/src/config.rs is the authority for this file. The distinguishing question its header asks is would a second machine running the same strategy need a different value? Store roots, log directories and listen addresses all answer yes, which is why they carry the full defaults → file → env → CLI chain: a container overrides a path with an environment variable, an operator overrides a port with a flag for one run, and neither is a risk decision. Contrast preferences.toml, whose values would be the same on the second machine, and policy.toml, which stops at the file layer on purpose.

Every key is optional, and an omitted path key does not mean no directory — it means the reading binary falls back to its own default, which is not the same for every binary. settings/config.example.toml says so explicitly and points at vike-cli config show's DEFAULT column as the authority per key.

The keys

keyenvironment variableabsent meanshot-appliable
store_rootVIKE_HIST_STOREthe caller's own fallbackno
log_dirVIKE_LOG_DIRvike-log's own fallbackno
journal_dirVIKE_JOURNAL_DIR—no
state_dirVIKE_STATE_DIRthe project rung, then <exe_dir>/strategy-stateno
datahub_addrVIKE_DATAHUB_ADDRthe backend's advertisement, else the local storeno
tradehub_addrVIKE_TRADEHUB_ADDRno control serverno
datahub_advertise_addrVIKE_DATAHUB_ADVERTISE_ADDRadvertise nothingno

The hot column comes from crates/vike-tradehub/src/hot_reload.rs, whose classification table has one row per key and whose the_hot_set_is_exactly_the_two_log_levels test pins the hot set to two preferences keys — so every config.toml key is restart-required. That is always the safe answer: the write is on disk, the next boot loads it, and the operator restarts and loses nothing.

store_root is the root of the DataFusion and Parquet history and tick store — see the history store. The field doc records why this key exists at all: VIKE_HIST_STORE had five rows in vike_ops::settings::SETTINGS, because vike-desktop, vike-backtest, vike-backfill, vike-datahub and vike-studio each read it with a different fallback chain. One field with one default is the fix, and the divergent fallbacks become the callers' business rather than the variable's. vike-desktop's row moved first: its studio_store_root takes Config::store_root and passes it to the same vike_model::store_path::resolve_store_root precedence it always used.

log_dir is where the rolling JSON trace log is written; absent, vike-log's own fallback applies. The example file flags the neighbouring trap in bold: this is not the size knob. The file layer defaults to trace and ignores RUST_LOG entirely, so the volume is turned down with preferences.log_file_level.

journal_dir is the live core's memory-mapped write-ahead command journal directory; the example file records that omitting it disables the journal.

journal_dir is the one key here whose file layer is still inert

vike_config::CONSUMPTION carries it as a written admission that nothing reads the field: VIKE_JOURNAL_DIR is read by crates/vike-core/src/run_profile.rs's journal_config_from_env, which resolves three variables at once — VIKE_RUN_PROFILE, VIKE_JOURNAL_DIR and VIKE_JOURNAL_SNAPSHOT_EVERY — and is called from vike-desktop, vike-tradehub and vike-run, so the whole family has to move together and the WAL directory stays an environment variable for now. Setting the key in config.toml configures nothing today; set the variable instead. vike-cli config show's READ column prints NO for it and the --json view carries that reason. Every other key on this page is read from the file.

state_dir is not the state root

Config::state_dir is the directory for program-written strategy state, and — as the example file puts it — it is vike-desktop's strategy-state sidecar directory, not the state root that vike-tradehub, vike-ops and vike-studio resolve. That root is <project>/settings/state/ and is not configurable from this file. The two have collided by name before; vike_model::state_path's module doc records it. Setting this key on a headless box does nothing, because only the GUI reads it. Absent, it resolves the project rung <project>/settings/state/strategy-state and falls back to <exe_dir>/strategy-state only when no project sits above the working directory — crates/vike-desktop/src/main.rs's state_dir_path is the resolver, and it takes that project rung off the boot's own walk rather than re-walking.

Three addresses, three jobs

The datahub_advertise_addr field doc enumerates them, because two of the three are easy to confuse:

  • tradehub_addr — where the daemon listens. This is vike-tradehub's bind address on the daemon's own box, and absent is the safe default: no control server at all, so the daemon trades headless with no network surface. The example file notes that setting it opens a socket, that observe is available to a peer holding an observe key, and that writes additionally need flags.tradehub_control — see flags and the node protocol.
  • datahub_addr — where this machine's client dials a vike-datahub data server, usually over an SSH tunnel. Presence is the branch: set, and vike-desktop's Studio takes its history from that server over RPC through a DataFusion-free RemoteHistStore, with the Studio's run backend also defaulting to remote at the same address; unset — the default — and a connected backend's advertisement fills in, with the local store at store_root's resolution only when neither answers (the desktop has no local engine, so that arm is an error naming both fixes instead). This field lost its old always-set default for exactly that reason. An explicit value here always wins over any advertisement.
  • datahub_advertise_addr — where the daemon tells clients to dial the datahub it fronts. Set it, and every Welcome.features the node server sends carries datahub=<value>, so a connected client with no datahub_addr of its own adopts it and one configured address reaches both planes. Absent advertises nothing. It is advertisement, never proxying: history and backtest traffic still dials the datahub directly, and nothing routes through the process holding live orders. Its value must be valid from the client's side of the wire — with the tunnel-only posture both servers ship with, that is the client-local tunnel mouth, not the daemon's private interface.

The vike-datahub server binary does not read this file at all: its own listen address is its own VIKE_DATAHUB_ADDR environment read, defaulting to DEFAULT_DATAHUB_ADDR, which is 127.0.0.1:7878. datahub_advertise_addr is consumed on the daemon's box, by vike-tradehub's start_observe_server.

Editing it

vike-cli config show --filter config prints which layer actually won on this box; the config verb covers the flags. A write through vike_config::set_setting preserves the file's comments and the formatting of every untouched line, validates the resulting text through the loader before a byte lands on disk, and renames atomically — so a crash mid-write leaves the old file intact rather than a truncated one.

On this page