Skip to content

Environment Variable Reference

Docs-site note (rewritten 2026-07-11): This page is grounded directly in source — the binary's own baked-default table and the per-flag getenv call sites that consume each variable — not in intent or naming. Where a flag's default changed since this page was first written (2026-06-25), that's because the binary itself changed: most of what used to be a manual deploy-script flag list is now filled in automatically. For the build-time (-D) side of the picture, see the Build-Flag Reference; for how these runtime variables reach the validator process during a deploy, see Deploying Vexor.


The short version

Vexor now bakes its own production defaults. The very first thing the binary does at startup — before any subsystem reads an environment variable — is fill in 23 VEX_* variables to their proven values, but only if you haven't already set them. An explicit value on your deploy command line always wins over the bake.

That means the honest, current operator surface is small: a handful of machine-specific variables (which binary, which cores, whether AF_XDP is available on this NIC) plus your keys and network address. Everything that used to be a long "remember all these flags" recipe is now a property of the binary itself. See the minimal recipe on the Build-Flag Reference page.

Two guards keep the bake safe:

  1. Production-only. The bake is skipped entirely when the binary detects an offline-replay or golden-gate context (VEX_LEDGER_REPLAY or VEX_SNAPSHOT_OFFLINE set). Those runs deliberately want the ledger write path, the watchdog's restart authority, and leader broadcast to stay off — baking them on would be actively wrong for a read-only replay.
  2. Machine facts are never baked. A fixed set of variables — which binary to run, hardware/NIC capability, core lists, snapshot freshness policy — legitimately differ from host to host and are deliberately left for the operator to set. See the minimal operator surface below.

Value-parse semantics

Most of the flags on this page follow one contract: unset means "let the binary decide" (baked default if there is one, otherwise off); an explicit 0 or false means "off, and this overrides the bake"; any other value — including the conventional 1 — means "on."

A few flags parse more strictly and only accept an exact "1" (or, on one flag, an exact "0") to arm or disarm; "true" / "yes" will not arm them. If you want a value that's guaranteed to work everywhere on this page, use 1 to turn something on and 0 to turn it off — both are accepted by every flag here, strict or not.


The baked necessity set

These 23 variables are set to the value below automatically at startup if you don't set them yourself. You do not need to put any of these in a deploy command for a standard testnet voting deploy — they're listed here so you know what a "default" boot is actually doing, and so you can force one off (=0) for a specific diagnostic session without a rebuild.

Variable Baked value What it actually does
VEX_LEDGER 1 Initializes the persistent VexLedger blockstore and spawns its write tile. See VexLedger.
VEX_DAG_DISPATCH 1 Enables the single-threaded conflict-DAG dispatcher on the replay path — the live transaction-ordering mechanism.
VEX_PARALLEL_EXEC 1 Arms wave-barrier parallel transaction execution inside the DAG dispatcher (requires VEX_DAG_DISPATCH, also baked on).
VEXOR_ED25519_FEC_DEDUP 1 Arms the Ed25519 FEC-set signature-dedup cache in the verify tile.
VEX_DISABLE_NETHASH 1 Despite the name, this value turns a liveness band-aid off: the node votes its own locally computed bank hash rather than falling back to a cluster-reported one.
VEX_LEADER_BROADCAST 1 Enables real leader-slot block broadcast instead of loopback-only. On its own this only ever produces empty, cluster-accepted blocks — it cannot make a block transaction-bearing by itself (see experimental flags below).
VEX_TURBINE_REAL_STAKES 1 Builds the turbine broadcast/retransmit tree from real epoch stake weights instead of a uniform stub (falls back to uniform, with a warning, if epoch stakes aren't populated yet).
VEX_STAKE_BPF 1 Routes stake-program instructions through the on-chain SBPF VM path instead of a native Zig implementation — the canonical path for testnet.
VEX_FORK_ISOLATION 1 Enables per-fork account-state isolation during replay. Strict parse: only an exact "1" arms it.
VEX_REPAIR_INFLIGHT 1 Arms in-flight repair-request tracking, so the same shred isn't re-requested while a request is already outstanding.
VEX_CATCHUP_ADAPTIVE_REFIRE 1 Arms adaptive repair re-fire behavior during catch-up.
VEX_VOTE_REFRESH 1 Re-sends the byte-identical last vote on a fresh blockhash if the node stalls without casting a new one — never a new vote, so it can't be a slashing risk by construction.
VEX_SWITCH_PROOF 1 Arms (not shadow-only) the cross-fork switch-threshold proof that authorizes voting a different fork than the node's current one, on top of — never instead of — the lockout check.
VEX_PROP_GATE 1 Refuses to vote a fork whose propagation hasn't been confirmed, when armed.
VEX_PROP_LATCH 1 Selects canonical leader-window propagation-latch target selection for vote targeting.
VEX_CANONICAL_VOTE 1 Arms canonical heaviest/canonical-leaf vote selection, the counterpart to VEX_SWITCH_PROOF above — the two are meant to run together. Added to the baked set after shipping separately (switch-proof armed, canonical selection unbaked) was traced to a recurring switch-proof stall.
VEX_VOTE_PREWARM 1 Arms targeted QUIC connect-ahead for validators the node expects to need shortly, in the vote poller.
VEX_DISABLE_CURL_VOTES 1 Forces the legacy curl/UDP vote-relay path off. Belt-and-suspenders: that path is already opt-in, so this mostly guards against it being turned on by accident.
VEX_REPAIR_SKIP_ABANDONED 1 Only takes effect when a cluster oracle also confirms a slot is genuinely abandoned — it is not a blind repair skip.
VEX_WATCHDOG_RESTART 1 Lets the liveness watchdog restart the process on a sustained wedge, instead of alert-only.
VEX_LEDGER_MAX_BYTES 107374182400 (100 GiB) Bounds on-disk ledger size; prunes the oldest whole segments once the cap is hit.
VEX_LEDGER_KEEP_SLOTS 216000 Alternate ledger-prune policy (keep the last N slots); the byte cap above takes precedence if both are set.
VEX_VOTE_FANOUT_ROTATIONS 3 Number of fanout rotations used when broadcasting a vote.

The minimal operator surface

These are the variables that legitimately vary per host and are never filled in automatically. Everything else that's genuinely load-bearing for a standard deploy is above.

Variable Purpose
VEX_BINARY Which pre-built binary to run.
VEX_ALLOW_NO_BN254 Required (=1) for a -Dpure_zig binary. The BN254 boot guard historically assumed a linked Firedancer Ballet BN254 library and refuses to boot without one; a pure-Zig binary has no such library by design (BN254/Poseidon run through Vexor's own vex_crypto instead), so this variable tells the guard that is expected. Not needed for a Ballet-backed (non--Dpure_zig) binary. See Building Vexor.
VEX_ENABLE_AFXDP Enables AF_XDP zero-copy networking on NICs that support it. Note: the transport switch itself comes from the corresponding CLI flags your deploy wrapper derives from this variable; the variable's own direct effect in the binary is narrower — a dedicated allocator arena for the receive thread and occupancy instrumentation. Set it wherever your deploy tooling expects it.
VEX_FRESH_SNAPSHOT 1 (recommended default) re-extracts the snapshot every boot and, if the local tarball is more than VEX_SNAP_MAX_AGE_SLOTS behind the live tip, downloads a fresh near-tip base+incremental pair. Working account cache, ledger, and tower state are wiped either way — this is the production-correct path, since it never inherits possibly-corrupt local state.
VEX_SNAP_MAX_AGE_SLOTS Freshness threshold for the check above, in slots. 0 forces a refetch on every boot; a very large value effectively preserves whatever local snapshot is already there.
VEX_REUSE_SNAPSHOT 1 boots from the existing local extracted-* snapshot without deleting or re-downloading it — the safe way to reproduce a specific slot for carrier diagnosis or regression repro. Working account cache, ledger, and tower are still wiped and rebuilt from that snapshot. Default 0 (off; use VEX_FRESH_SNAPSHOT behavior instead).
VEX_PARALLEL_EXEC_CORES Which CPU cores host the parallel-execution worker pool. Hardware-specific — see Hardware.
VEX_TASKSET_CORES The process-wide CPU affinity mask. Hardware-specific.
VEX_UMEM_RESERVE AF_XDP UMEM frame reservation count.

Identity keypair, vote keypair, public IP, ports, cluster entrypoints, and data-directory paths are CLI arguments, not environment variables — see the Build-Flag Reference minimal recipe for an example and your deploy tooling's own flags for the full argument list.


Experimental, keep-gated flags (not production)

These compile in and ship in the binary, but are deliberately left off by default and off in the baked-default list — they're real, working code paths that haven't earned a place in the standard deploy yet.

Variable What it does Status
VEX_TPU_INGEST Enables transaction ingest into an in-memory mempool, independent of block broadcast. Not production. Safe on its own (loopback only), but see the interlock below.
VEX_TXBEARING_BROADCAST The interlock that would let a broadcast block actually carry transactions (instead of an empty, cluster-accepted block). Not production. Combined with VEX_TPU_INGEST and broadcast, transaction-bearing blocks currently diverge from cluster consensus and get skipped. Leave this off; produced blocks stay empty and valid without it.
VEX_FORCE_INLINE_PRODUCE Gated, working code path. Not production. Confirm the exact effect in source before relying on it — not covered in operator-facing deploy guidance.
VEX_GOSSIP_PROP Gated, working code path. Not production. Confirm the exact effect in source before relying on it — not covered in operator-facing deploy guidance.
VEX_BLOCK_DAG Gated, working code path. Not production. Confirm the exact effect in source before relying on it — not covered in operator-facing deploy guidance.

Diagnostic and forensic flags

Everything in this category defaults off, is intended for parity investigations or crash forensics, and has no place in a normal deploy. Rather than list every individual name, here's the shape of what exists, grouped:

Category What it's for Examples
Account read/write recorder Per-slot account access tap for parity investigations VEX_RECORD_READS, VEX_RECORD_WRITES, VEX_RECORD_SLOTS
State/field dumps Dump bank or account state at a given point VEX_FREEZE_DUMP_SLOT, VEX_ACCT_DUMP, VEX_DUMP_ENTRY
Lt-hash verification Verify or trace the accounts lt-hash VEX_VERIFY_LTHASH_SLOT, VEX_VERIFY_LTHASH_WRITES, VEX_LT_DELTA
Vote / gossip probes Byte-level vote and gossip transport diagnostics VEX_VOTE_PROBE, VEX_PROBE_SYSVAR_BYTES, VEX_PROBE_IDENTITY
SBPF VM debug BPF interpreter tracing VEX_CALLX_DEBUG, VEX_VMFAULT_DEBUG, VEX_BPF_DBG_PROBES
KAT / fixture replay Known-answer-test harness inputs VEX_KAT_HASH, VEX_FIXTURE_ONLY
Allocator debug Swap in Zig's checked debug allocator to catch use-after-free with a real stack trace VEX_DEBUG_ALLOC — slow, boot only to hunt a crash, never for production

If you're chasing a specific consensus or performance question and think one of these is relevant, it's worth confirming the exact call site in source before relying on it — some historical variable names in older deploy notes turn out to have no live effect in the current binary.


Metrics — SOLANA_METRICS_CONFIG

Vexor reports metrics using the same environment variable and format as Agave:

SOLANA_METRICS_CONFIG="host=<url>,db=<database>,u=<user>,p=<password>"

If the variable is unset or fails to parse, the metrics reporter logs that it's disabled and the validator runs normally — there's no metrics-config requirement to vote. For the public testnet metrics write endpoint and credentials, see Anza's cluster documentation rather than copying a value from anywhere else — those are the canonical, current values for the cluster you're joining.


VEX_MODE (planned)

A single VEX_MODE switch is planned to select the validator's role in one step, replacing the current mix of individual flags for the same decision:

Value Role
full (planned default) Vote and produce blocks — today's behavior.
vote Vote only; never produce or broadcast blocks.
rpc Follow the cluster only — no voting, no block production.

This has not shipped yet. It's designed as a thin macro over the existing VEX_LEADER_BROADCAST flag plus one new voting-enable gate, specifically so that full mode remains byte-identical to current behavior. Once it lands, this page will be updated with the shipped specifics; until then, the baked necessity set above reflects the only mode that exists today (full: vote + produce empty, cluster-accepted blocks).


Status

This page reflects the binary's own baked-default table and the source getenv sites that consume each variable, audited directly against source rather than inferred from deploy-script history or variable names. If a flag you're relying on isn't listed here, treat it as unproven for production use until you've confirmed its effect in source. See Deploying Vexor for the ordered contract these variables are consumed by, and Building Vexor for the -D build flags a handful of them arm at runtime.