Environment Variables
QUBIQ reads configuration from the environment and from a .env file in its
data directory. The file is created
automatically on first boot with generated secrets.
Most of these are set for you by the installer. Edit .env only for the deployment-specific
settings — TLS, allowed origins, trusted proxies, login policy.
.env holds ENCRYPTION_KEYLosing it makes every stored connection credential and the configuration database unrecoverable. Back it up separately from the data directory, and never commit it.
Secrets
| Variable | Default | Description |
|---|---|---|
JWT_SECRET | required | Protects Platform sign-ins. Generated on first run. Missing ⇒ hard startup failure — there is no insecure default. |
ENCRYPTION_KEY | required | 64 hex characters. Derives the key protecting the configuration database and connection secrets. Generated on first run. Missing or malformed ⇒ hard startup failure. |
LIVE_JWT_SECRET | derived from JWT_SECRET | Protects LiveView sign-ins. Set it explicitly if you want to reset operator sign-ins without affecting engineers. |
Network
| Variable | Default | Description |
|---|---|---|
PORT | 8182 | CoreServer HTTP/WS port — the interface and API |
REALTIME_PORT | 8183 | RealtimeGateway telemetry WebSocket |
REST_GATEWAY_PORT | 8090 | RestGateway — pipeline-published REST ingress |
SCRIPTING_GATEWAY_PORT | 8091 | ScriptingGateway |
HOST | 0.0.0.0 | Bind address |
ALLOWED_ORIGINS | http://localhost:3000,http://localhost:5173 | Comma-separated CORS origins. Set this to your real origins in production. |
TRUSTED_PROXIES | (none) | Comma-separated CIDRs or IPs. Without it, X-Forwarded-For is ignored and the peer address is used — so a spoofed header cannot rotate the login-lockout bucket. |
TLS and cookies
| Variable | Default | Description |
|---|---|---|
TLS_ENABLED | false | Terminate TLS at QUBIQ |
TLS_CERT_FILE | (none) | Certificate chain path |
TLS_KEY_FILE | (none) | Private key path |
QUBIQ_COOKIE_SECURE | follows TLS_ENABLED | Force the Secure cookie flag. Set it when a proxy terminates TLS but this process serves HTTP. |
CSRF_ENABLED | true | CSRF protection |
Cookie Secure derives from TLS so that an HTTP-only on-premise deployment is never broken by an
unsendable cookie — with the explicit override for the proxy case.
Authentication
| Variable | Default | Description |
|---|---|---|
LOGIN_MAX_ATTEMPTS | 10 | Failures before lockout |
LOGIN_WINDOW | 15m | Window in which failures are counted |
LOGIN_LOCKOUT | 15m | Lockout duration |
QUBIQ_KEEP_SESSIONS | false | true keeps engineers and operators signed in across a gateway restart; by default a restart signs everyone out. Same as Keep sessions across restarts in the security settings. 1.0.8 |
The sign-in settings above — and CSRF_ENABLED, ALLOWED_ORIGINS, TRUSTED_PROXIES,
QUBIQ_COOKIE_SECURE — can also be changed in Settings → Security Policy. While one is set in the
environment it wins, and its field in Settings is locked; remove it from .env and the value last
saved in Settings takes over. → Security overview
Paths and storage
| Variable | Default | Description |
|---|---|---|
QUBIQ_DATA_DIR | Set by the installer | The data directory. Pinned at install time so a service account with no user profile resolves it. |
ENVIRONMENT | production (set by the installer) | Deployment mode. |
DATABASE_PATH | in the data directory | Configuration database |
QUBIQ_DB_ENCRYPTION | on | on/off. Applies to a fresh database only — there is no migration; the configuration database must be deleted to change mode. |
Uploads and library folders are not environment variables. They are configured in
Settings → Storage Folders and stored in the database, so there is one source of truth. Until set, storage
fails closed.
Execution
| Variable | Default | Description |
|---|---|---|
PYTHON_PATH | The bundled runtime, set by the installer | Interpreter for the Python worker. Do not repoint this at a system Python — the bundled runtime is version-pinned against the worker. |
PYTHON_WORKER_REPLICAS | (platform default) | Parallel Python workers |
EXECUTION_TIMEOUT | 5m | Default execution timeout |
MAX_CONCURRENT_JOBS | 10 | Concurrent execution ceiling |
QUBIQ_BROWSER_SCRIPT_SCOPES | on | off restores the earlier behaviour, where a Gateway script started from a browser button ran unclamped. On, its capabilities are derived from the caller's own realm and write level. → The sandbox 1.0.4 |
Connections and liveness
| Variable | Default | Description |
|---|---|---|
LIVENESS_MODE | passive | passive (5 min safety-net probe), hybrid (30 s), active (10 s, probe everything) |
LIVENESS_MODE is read once, to seed Settings → System Health; after that the setting there is
what applies.
AI time limits New in 1.0.8
| Variable | Default | Description |
|---|---|---|
AI_TURN_TIMEOUT_SEC | 180 | Chat answer limit, in seconds |
AI_AGENT_TIMEOUT_SEC | 120 | AI node limit, in seconds |
AI_TOOL_CALL_TIMEOUT_SEC | 30 | Tool call limit, in seconds |
AI_COMPUTE_TIMEOUT_SEC | 60 | Compute specialist limit, in seconds |
These only supply the defaults of the AI time limits card, read by QBQ-AI when it starts.
A limit saved on the card wins over them and applies from the next turn without a restart; set the
limits there. → Time limits
Message bus New in 1.0.8
| Variable | Default | Description |
|---|---|---|
QUBIQ_JETSTREAM_SYNC | 5s | How often the bus's durable store — the store-and-forward buffers, the quarantine, the audit buffer — is forced to disk. A Go duration, clamped to 100 ms – 2 min (1s for a tighter power-cut window). always fsyncs every write: only for storage proven to take it; on an ordinary disk it slows buffered writes to about ten a second. Unset or unreadable means 5 s. |
QUBIQ_NATS_READY_TIMEOUT | 15m | How long the supervisor waits for the bus to restore its store on start-up before giving up. After an unclean stop with a large backlog the restore takes a while; progress is logged every 10 seconds. A Go duration, e.g. 30m. |
Historian
| Variable | Default | Description |
|---|---|---|
HISTORIAN_SF_MAX_BYTES | 25 % of the data volume, at least 2 GiB | Size of the historian's store-and-forward buffer, in bytes. A value saved in Settings → Store & Forward → Buffer limits overrides it. 1.0.8 |
HISTORIAN_SF_MAX_AGE_HOURS | (no age limit) | Age limit of the historian's buffer, in hours. Overridden by Buffer limits. 1.0.8 |
HISTORIAN_SF_FULL_POLICY | refuse_new | refuse_new keeps the backlog and refuses new samples when the buffer is full; drop_oldest discards the oldest. Overridden by Buffer limits. 1.0.8 |
HISTORIAN_CARRY_MAX_HOLD | 8h | How long the historian carries an on-change tag's last value across empty chart buckets. A Go duration; 0 turns carrying off. 1.0.8 |
HISTORIAN_CLOCK_SKEW_ALARM | 2m | How far a device's timestamps may run from the gateway's clock before the clock-skew alarm is raised. A Go duration; 0 turns the alarm off. 1.0.8 |
HISTORIAN_TWA_RAW_MAX_DAYS | 7 | The longest range, in days, for which time-weighted statistics are computed exactly from raw samples; longer ranges read the 1-hour tier. 1.0.8 |
QUBIQ_HISTORIAN_HEARTBEAT_MAX_SILENCE | 24h | A tag's heartbeat rows stop after this long with no real value, even if its source still looks alive. A Go duration. 1.0.8 |
HISTORIAN_ROLLUP_MIN_WINDOW_SEC | 43200 (12 h) | The smallest chart window, in seconds, served from the rollups. Shorter windows read the raw table, which is already fast at that range and finer than one-minute buckets. |
HISTORIAN_ROLLUP_REBUILD_MAX_ROWS | 10000000 | Raw-table size, in rows, above which an out-of-date rollup is not rebuilt automatically at start-up — on a large historian a rebuild is a maintenance action to start deliberately. 0 or a negative value removes the guard. → Rollup rebuild |
HISTORIAN_ROLLUP_REFRESH_EVERY | 5m | Fleet-wide default for how often the 1-minute rollup re-aggregates. A connection's own Rollup Refresh Every overrides it. |
HISTORIAN_ROLLUP_PARTITION | HOUR | Fleet-wide default partition unit of the 1-minute rollup: HOUR, DAY, WEEK, MONTH or YEAR. A connection's own Rollup Partition overrides it. |
HISTORIAN_ROLLUP_MAX_STALENESS | 15m | How far the rollup's newest bucket may lag the clock and still be used. A staler rollup is bypassed and the whole window read from raw until it catches up. A Go duration. |
HISTORIAN_ROLLUP_REFRESH_LIMIT | 7d | How far back an incremental rollup refresh folds in late rows, so a stray far-past timestamp cannot invalidate the rollup. A full rebuild ignores it. off removes the limit. |
HISTORIAN_ROLLUP_AUTOCREATE | (on) | off stops the historian creating the rollup view — for a QuestDB build without materialized views. Charts then read raw. |
HISTORIAN_OWNERSHIP | (on) | off stops enforcing store ownership — an escape hatch for deliberately shared access, or to recover from a bad claim. |
HISTORIAN_SERIES_CACHE | (on) | off bypasses the gateway's cache of chart series queries. |
HISTORIAN_QUERY_CONCURRENCY | 16 | Read once, to seed Settings → Historian → Max parallel queries; after that the setting there applies. → Query concurrency |
First-run bootstrap
| Variable | Default | Description |
|---|---|---|
QUBIQ_INIT_ENV | production | The ENVIRONMENT written into a generated .env |
QUBIQ_INIT_PYTHON | The bundled runtime | The PYTHON_PATH written into a generated .env |
QUBIQ_OPEN_BROWSER | (unset) | Open a browser on start |
Diagnostics
| Variable | Default | Description |
|---|---|---|
QUBIQ_MERGE_DEBUG | (unset) | 1 logs the historian's live-tail merge decisions per series query. Look for [MERGE] in the historian's output. Off by default; for tuning flush-lag only. |
Sample .env
# --- Written by the installer; do not hand-edit ---
ENVIRONMENT=production
QUBIQ_DATA_DIR=/var/lib/qubiq
PYTHON_PATH=/opt/qubiq/python/bin/python3
# --- Generated on first boot. Back these up SEPARATELY from the data dir ---
JWT_SECRET=<64 hex chars>
ENCRYPTION_KEY=<64 hex chars>
LIVE_JWT_SECRET=<64 hex chars>
# --- Yours to set for this deployment ---
PORT=8182
REALTIME_PORT=8183
REST_GATEWAY_PORT=8090
SCRIPTING_GATEWAY_PORT=8091
ALLOWED_ORIGINS=https://qubiq.example.com
TRUSTED_PROXIES=10.0.0.0/8
QUBIQ_COOKIE_SECURE=true # TLS terminated at a reverse proxy
LOGIN_MAX_ATTEMPTS=5
LOGIN_WINDOW=15m
LOGIN_LOCKOUT=30m
Precedence
- Process environment
.envin the data directory- Built-in defaults
.env is generated with owner-only permissions (0600) on first boot.
Next
→ Glossary