Environment variables
Reference for every environment variable FlexTool reads at runtime, grouped by what they do. All variables are optional — defaults preserve the user-facing behaviour and add zero overhead.
Two reasons to set any of them:
- Functional toggles — change what FlexTool does (autoscale mode, save-memory subprocess solver, HiGHS options).
- Diagnostics — record memory or timing for post-hoc analysis.
CLI flags on run_flextool.py take precedence and, where they map to
an env var, set it for the rest of the process. Direct env-var use is
the right path when you cannot pass a flag (Spine Toolbox execution,
GUI subprocess, CI matrix).
For the polar_high solver kernel's own env vars (profiling MPS
writes, autoscale range readout cap), see the
polar-high environment-variables page.
Functional toggles
| Variable | Default | Set to | What it does |
|---|---|---|---|
FLEXTOOL_SCALING |
full |
off / solver_only / basic / full |
Autoscale mode. Equivalent to --scaling <mode>. off skips Layers 2/3 (Layer 1 always runs for the YAML audit). See LP scaling pipeline. |
FLEXTOOL_USER_BOUND_SCALE |
unset | integer (e.g. 6) |
Pin the HiGHS Layer-3 user_bound_scale exponent instead of auto-picking. Equivalent to --user-bound-scale N. |
FLEXTOOL_SAVE_MEMORY |
unset (off) | 1 |
Enable the polar-high subprocess-solver path (writes MPS, shells out, frees parent-process LP buffers before the solve). Equivalent to --save-memory. Trades wall time for peak RSS. |
HiGHS tuning
Each maps to a HiGHS option threaded through
_orchestration._finalise_highs_options. Setting the env var is
equivalent to passing the matching CLI flag on run_flextool.py.
| Variable | Default | Set to | What it does |
|---|---|---|---|
FLEXTOOL_HIGHS_TIME_LIMIT |
HiGHS default | seconds (float) | HiGHS time_limit option. Hard wall-clock cap per solve. |
FLEXTOOL_HIGHS_PRESOLVE |
HiGHS default (on) |
on / off / choose |
HiGHS presolve option. Equivalent to --presolve. Useful when comparing warm-vs-cold solves. |
FLEXTOOL_HIGHS_THREADS |
HiGHS default | positive integer | HiGHS threads option. Equivalent to --highs-threads. |
Memory diagnostics
All diagnostics are off by default and impose zero overhead when unset.
| Variable | Default | Set to | What it does |
|---|---|---|---|
FLEXTOOL_MEMORY_DIAGNOSTICS |
unset (off) | 1 |
Enable the per-checkpoint memory recorder. Activates tracemalloc (so traced_peak is meaningful) and writes solve_data/memory_diagnostics.csv for post-hoc analysis. --debug sets this. |
FLEXTOOL_MEMORY_VERBOSE |
unset (off) | 1 |
Drop the whitelist filter on the standard [mem] log table so every phase checkpoint is printed. --debug sets this. |
FLEXTOOL_AUTOSCALE_PROFILE |
unset (off) | 1 |
Per-substep RSS markers around the autoscale orchestration. Complements POLAR_HIGH_RANGES_PROFILE from polar-high — set both when range detection itself is suspect. |
FLEXTOOL_PYRAMID_PROFILE |
unset (off) | 1 |
Wired through _MemoryRecorder.checkpoint(): after every emit_* call in _emit_solve_time.run (the per-solve preprocessing pyramid), emit a tab-separated stderr line in the polar-high [pyramid profile] phase=… rss_gb=… delta_gb=… t_s=… format (precedent: POLAR_HIGH_WRITE_MPS_PROFILE). Zero overhead when unset; combine with FLEXTOOL_MEMORY_DIAGNOSTICS=1 to also persist a CSV trace. |
FLEXTOOL_PHASE_TIMING |
unset (off) | 1 |
Per-iter per_iter rows added to the workdir's timings.csv covering lp_build / solve / handoff plus a warm_used marker. Use for rolling / warm-chain wall-time breakdowns. |
FLEXTOOL_MEM_SAMPLER |
unset (off) | 1 (or any truthy: true, yes) |
Start an in-process daemon-thread RSS sampler at startup. Writes one row per sample to the log path below. Independent of the phase recorder — useful when the recorder's coarse checkpoints miss a transient peak. |
FLEXTOOL_MEM_SAMPLER_LOG |
/tmp/flextool_mem_sampler_<pid>.log |
filesystem path | Sampler output path. Only consulted when the sampler is on. |
FLEXTOOL_MEM_SAMPLER_INTERVAL_MS |
100 (clamped 20–10000) |
integer milliseconds | Sampler cadence. Tighter intervals catch shorter peaks at the cost of more log volume. |
Example — find a transient RSS peak the per-phase recorder is missing:
FLEXTOOL_MEM_SAMPLER=1 FLEXTOOL_MEM_SAMPLER_INTERVAL_MS=50 \
python run_flextool.py input.sqlite output_info.sqlite --scenario-name base
Memory tuning
| Variable | Default | Set to | What it does |
|---|---|---|---|
MALLOC_ARENA_MAX |
4 (set by flextool/cli/cmd_run_flextool.py at startup) |
integer (e.g. 1, 2, 8) |
Cap on per-thread glibc malloc arenas. Linux-only. Defaults to 4 because polars / Arrow allocate-and-free in patterns that otherwise fragment per-thread arenas into a large RSS footprint that is not reclaimed between solves. Lower (1 or 2) further trims long-running rolling-horizon RSS at a small allocator-contention cost; higher relaxes the cap if you suspect arena contention is dominating. Not a FlexTool-defined variable — the entry point sets a default via os.environ.setdefault, so any value already in the environment wins. |
FLEXTOOL_COLD_KEEP_PROVIDER |
unset (off) | 1 |
Under --save-memory, keep the flex_data_provider alive across cold iterations instead of rebuilding from the Spine DB each time. Trades steady-state RSS for skipping a per-iter DB re-read. Off by default because peak RSS is the typical save-memory bottleneck. |
FLEXTOOL_RSS_BUDGET_MB |
unset (no eviction) | MB (float) | Soft RSS budget for the flex_data_provider's lazy-frame eviction. When set, the provider drops cached frames once RSS crosses the threshold (subject to lifetime info). Useful on long-running workflows where intermediate frames accumulate; unset gives unbounded retention. |
Precision cleanup
| Variable | Default | Set to | What it does |
|---|---|---|---|
FLEXTOOL_PRECISION_DIGITS |
unset (passthrough) | integer 1–15 | Round every numeric CSV cell written to input/ / solve_data/ to N significant figures. Env-var fallback for --precision-digits N. 0 or unset disables. CLI takes precedence. See LP scaling pipeline § Precision rounding. |
FLEXTOOL_REPORT_NEAR_DUPS |
unset (off) | 1 / true / yes / on |
Run the near-duplicate parameter-value diagnostic. Off by default; equivalent to --report-near-duplicates. Surfaces clusters of values that are nearly-but-not-exactly equal — useful before tightening FLEXTOOL_PRECISION_DIGITS. |
Niche / test hooks
These are documented for completeness. Most users will never set them.
| Variable | Default | Set to | What it does |
|---|---|---|---|
FLEXTOOL_NATIVE_SCENARIO |
unset | scenario name | Override for run_chain's scenario-name resolution when neither the dir-name convention (work_<scenario>) nor an explicit kwarg applies. |
FLEXTOOL_SOLVER_CONFIG_DIR |
<cwd>/solver_config |
directory path | Override the lookup directory for highs.opt and friends used by the subprocess-solve path. Matches the existing hook honoured by CI / tests. |
FLEXTOOL_DUMP_CSVS |
unset (off) | 1 |
Restore the legacy debug-oracle CSV writes — emits the seven gigabyte-scale CSVs that dump_csvs skips by default. Used by the round-trip regression test; for normal runs the default (skip) saves significant disk I/O. |
FLEXTOOL_AUDIT_SOURCES |
unset (off) | 1 |
Append every Provider key carrying a non-None source tag to <work_folder>/audit_sources.log per sub-solve. Captures externally-injected entries from the override translator. |
FLEXTOOL_FORCE_ROW_SCALING |
unset | 1 / true / yes / on |
Test hook that forces p_use_row_scaling=1. Since the solve.use_row_scaling DB parameter was removed, every solve emits p_use_row_scaling=0 by default and this hook is the only way to enable the legacy row-scaling family. Used by the Mode B un-scaling benchmark harness. |
FLEXTOOL_SKIP_SOLVER_PROBE |
unset | 1 |
Skip the startup solver-license probe (avoids the FICO Xpress Community LicenseWarning). Set in the test conftest. |
FLEXTOOL_SLICE |
unset | systemd slice name | When set and systemd-run is available, place the worker process in the named cgroup slice for scheduling isolation. GUI-launched runs only. |
FLEXTOOL_DPI |
unset (auto-detect) | DPI value (e.g. 144) |
GUI-only. Explicit DPI override when desktop-environment auto-detection (Xft.dpi, GDK_SCALE, Windows ctypes query) gives the wrong value. |
See also
- LP scaling pipeline — the full autoscale story for
FLEXTOOL_SCALINGandFLEXTOOL_USER_BOUND_SCALE. - polar-high — Environment variables —
the kernel-side
POLAR_HIGH_*profiling and tuning variables.FLEXTOOL_SAVE_MEMORY=1enables the path wherePOLAR_HIGH_WRITE_MPS_PROFILE=1is most informative.