Skip to content

Configuration Overview

ForecastAI 2026.01 (Mirabelle) uses a two-layer configuration system designed so that the application can bootstrap from a minimal file and then load all runtime behaviour from the database.


Layer 1 — files/config/config.yaml

This file contains only the database connection information needed to connect to PostgreSQL on startup. Nothing else belongs here.

database:
  host: 127.0.0.1
  port: 5432
  database: forecastai          # tenant database name
  user: postgres
  password: your_password
  schema: scenario
  sslmode: disable

All other keys you may have seen in older versions of this file (forecasting parameters, outlier thresholds, etc.) have been migrated to the database. The file is intentionally minimal so that a fresh installation only requires editing one block.

Do not add pipeline parameters here

Parameters such as forecasting.horizon or characterization.adi_threshold placed in config.yaml will be ignored at runtime — the system reads from scenario.parameters instead. Only the database: block is honoured from the file.

Environment variable fallbacks

If config.yaml is absent, the database loader in files/db/db.py falls back to environment variables:

Variable Purpose
DB_HOST PostgreSQL host
DB_PORT Port (default 5432)
DB_NAME Database name
DB_USER Username
DB_PASSWORD Password
DB_SCHEMA Schema (default scenario)
DB_SSLMODE SSL mode (default disable)

A .env file in the files/ directory is auto-loaded on API startup.


Layer 2 — scenario.parameters table

All pipeline behaviour is stored in the parameters table within each tenant's scenario schema. The function load_config_from_db() assembles these rows into the config dict that every pipeline module reads.

Table structure

CREATE TABLE scenario.parameters (
    id              SERIAL PRIMARY KEY,
    parameter_type  TEXT NOT NULL,        -- 'forecasting', 'characterization', etc.
    name            TEXT NOT NULL,        -- e.g. 'Default Forecasting'
    label           TEXT,                 -- display label for the UI
    parameters_set  JSONB NOT NULL,       -- the actual key/value configuration
    description     TEXT,
    is_default      BOOLEAN DEFAULT FALSE,-- exactly one per parameter_type is the fallback
    sort_order      INTEGER DEFAULT 0,
    updated_at      TIMESTAMPTZ,
    created_at      TIMESTAMPTZ DEFAULT NOW()
);

Each row represents one parameter version (also called a parameter set) for a given type. Multiple versions of the same type can coexist — one must be marked is_default = TRUE and serves as the global fallback.

Supported parameter_type values

Type What it controls
forecasting Models enabled, horizon, Dask workers, neural model flags
characterization ADI threshold, CV² threshold, seasonality test settings
outlier_detection IQR multiplier, z-score threshold, STL parameters
evaluation Backtesting windows, metrics to compute
best_method Metric weights for composite scoring
valuation Unit cost source, holding rate
supply Reorder parameters, safety stock defaults
meio Fill-rate targets, budget cap, safety stock method

How the system reads parameters

At startup (and after POST /api/reload) the API calls load_config_from_db() which:

  1. Reads all rows where is_default = TRUE.
  2. Assembles them into a nested dict keyed by parameter_type.
  3. Returns that dict as the runtime config — identical in shape to the old config.yaml.

Pipeline modules then call load_config_from_db() themselves at the start of each run, so they always use the latest values without needing a restart.

Editing parameters

Parameters can be edited through the Settings page (/settings) in the UI, which calls PUT /api/parameters/{param_id}. Changes are written directly to the database and take effect on the next pipeline run or API reload.

For programmatic edits:

PUT /api/parameters/{param_id}
Authorization: Bearer <token>
Content-Type: application/json

{
  "parameters_set": {
    "horizon": 26,
    "min_obs": 12
  }
}

Multi-tenancy and parameters

In a multi-tenant deployment, each tenant has its own scenario schema in its own database. Parameters are therefore per-tenant — changing a parameter for one tenant does not affect others.

The ParameterResolver (documented in Parameters) goes one level further: within a tenant, different series or segments can use different parameter versions, allowing segment-specific forecasting configurations without duplicating pipeline runs.


Configuration precedence (summary)

config.yaml (database connection only)
    ↓ bootstrap connection
scenario.parameters (is_default=TRUE rows)
    ↓ global defaults for all series
scenario.series_parameter_assignment (segment-based)
    ↓ overrides for series in a segment
scenario.series_hyperparameters_overrides (per-SKU)
    ↑ highest priority

See Parameter System for the full three-level resolution logic.


Planning Date

In addition to pipeline parameters, the system supports a planning date override that shifts the effective "today" for all business logic. This is critical for replay, backtesting, and demo environments.

See Planning Date System for the full documentation.


Adaptive CPU Autoscaling

The system supports adaptive CPU scaling for long-running pipeline steps (forecast, backtest, distribution fitting). A background thread samples CPU utilization and dynamically raises the Dask worker count when cores sit idle. MEIO and supply steps run in monitor-only mode (their Rust rayon pool is fixed at startup). Configured via the ⚡ Autoscale subtab in the Processes → Cluster tab.

See Adaptive CPU Autoscaling for the full documentation.