Configuration
This page is a guided map of what the Enterprise binary lets you tune. For the OIDC and Temporal blocks, see the dedicated pages.
Profile and configuration file
The backend loads its YAML config:
| Variable | Purpose |
|---|---|
CONFIG_FILE | Absolute path to a config file. |
Precedence is environment variable → YAML value → built-in default. So any field documented below as having an environment-variable name can be overridden at runtime without touching the YAML file.
REST API
The HTTP server that serves both the REST API and (optionally) the metrics endpoint.
| Variable | Default | Purpose |
|---|---|---|
REST_API_PORT | 8080 | Public API listen port. |
REST_API_CONTEXT | / | URL prefix. Set to e.g. /api/v1 when sitting behind a path-based reverse proxy. |
REST_READ_TIMEOUT | 30s | HTTP request read timeout. |
REST_WRITE_TIMEOUT | 60s | HTTP response write timeout. Streaming endpoints (NDJSON exports) are bounded by this. |
REST_IDLE_TIMEOUT | 120s | Keep-alive idle connection timeout. |
REST_MAX_HEADER_BYTES | 1 MiB | Max request header size. |
REST_MAX_BODY_BYTES | 5 MiB | Max request body size. Raise if you deploy large BPMN/DMN XML uploads. |
REST_ALLOWED_CORS_ORIGINS | - | Comma-separated CORS origin allowlist. Set to your SPA origin(s) in production. Wildcard is not supported. |
REST_ALLOWED_WS_ORIGINS | - | Comma-separated WebSocket origin allowlist (used by the FEEL editor's LSP). |
REST_METRICS_PORT | 9464 | Prometheus /metrics endpoint port. Separate HTTP server from the API. |
REST_METRICS_ADDR | empty (all interfaces) | Bind address for the metrics server. Set to 127.0.0.1 to keep telemetry off ingress, or firewall the port. |
Database
Connection settings for PostgreSQL. Internal schema migrations run automatically on every startup — there is no separate migration step.
| Variable | Default | Purpose |
|---|---|---|
DB_HOST | localhost | PostgreSQL hostname. |
DB_PORT | 5432 | PostgreSQL port. |
DB_USER | - | PostgreSQL user. |
DB_PASSWORD | - | PostgreSQL password. |
DB_NAME | - | Database name. |
DB_SSLMODE | disable | disable, require, verify-ca, or verify-full. |
DB_MAX_CONNS | 50 | pgxpool max connections. Raise for high BPMN concurrency. |
DB_MIN_CONNS | 5 | pgxpool min connections kept warm. |
OIDC
See Authentication for the full picture. The five tunable variables are OIDC_ISSUER, OIDC_CLIENT_ID, OIDC_AUDIENCES, OIDC_ROLES_CLAIM, OIDC_PROJECTS_CLAIM.
Temporal
See Temporal setup. The Temporal block has a deep tail of connection, TLS, and tuning knobs — TEMPORAL_HOST_PORT, TEMPORAL_API_KEY[_FILE], the TEMPORAL_TLS_* family, the TEMPORAL_CONN_* family, and TEMPORAL_CAN_* for long-running workflows.
Caching
Two independent caches.
Access cache — caches the project-UUID → PostgreSQL schema-name lookup so request routing doesn't hit projects.schema_name on every call. Role and membership are read from the JWT every request and are not cached.
| Variable | Default | Purpose |
|---|---|---|
ACCESS_CACHE_MAX_SIZE | 100 | Max cache entries. Bump above your project count to eliminate cold-miss lookups. |
ACCESS_CACHE_TTL | 30s | Cache entry time-to-live. Pure performance knob — see Operations → Access cache. |
Compiled DMN cache — caches compiled decision tables so evaluation doesn't re-parse them on every call.
| Variable | Default | Purpose |
|---|---|---|
COMPILED_CACHE_MAX_SIZE | 100 | Max compiled tables held in memory. The cache is per-replica, expect cold misses after deploys or replica rotation. |
FEEL evaluation budgets
Caps on what a single FEEL expression can do. They protect against pathological or hostile input, defaults are unreachable for normal expressions.
| Variable | Default | Purpose |
|---|---|---|
FEEL_MAX_DEPTH | 256 | Max recursion depth in evaluation. 0 disables the cap. |
FEEL_MAX_ITERATIONS | 1000000 | Max combined iterations across all for / some / every loops in one evaluation. 0 disables the cap. |
FEEL_DEFAULT_TIMEOUT | 5s | Wall-clock timeout. Enforced via context cancellation. 0 disables the default. |
BPMN engine
The operator-facing subset of the BPMN configuration. A worker here means a Temporal worker (workflow + activity poller pair) running against one tenant's namespace.
| Variable | Default | Purpose |
|---|---|---|
BPMN_MAX_CALL_ACTIVITY_DEPTH | 64 | Max recursion depth for callActivity chains. |
BPMN_DEFAULT_WORKERS | 1 | Default number of Temporal workers per project. |
BPMN_TIMER_POLLER_INTERVAL | 30s | How often the engine checks for due timer events. |
BPMN_INSTANCE_RECONCILER_INTERVAL | 30m | How often the reconciler scans for drift between PostgreSQL state and Temporal. |
Per-tenant worker counts can be overridden in YAML:
bpmnWorkers:
defaultWorkers: 1
overrides:
"<project-uuid>": 4
Observability
| Variable | Default | Purpose |
|---|---|---|
ENABLE_OTEL | false | Enable Prometheus metrics export on REST_METRICS_PORT. See Operations → Observability for what's actually exported. |
Advanced tuning
- BPMN worker concurrency —
BPMN_MAX_CONCURRENT_ACTIVITY_TASK_POLLERS,BPMN_MAX_CONCURRENT_WORKFLOW_TASK_POLLERS,BPMN_MAX_CONCURRENT_ACTIVITY_EXECUTION_SIZE,BPMN_MAX_CONCURRENT_WORKFLOW_TASK_EXECUTION_SIZE. Defaults are computed from worker count, override if you're tuning a worker for unusual load shapes. - External job lease tuning —
BPMN_LEASE_DURATION,BPMN_LEASE_REFILL_PER_WAITER,BPMN_LEASE_REFILL_MAX_BATCH,BPMN_LEASE_POLL_WAKE_BUFFER,BPMN_LEASE_BATCH_HOLD,BPMN_LEASE_BATCH_SAFETY_MARGIN. These control how external jobs are leased to workers, defaults are tuned for typical workloads. - Temporal connection tuning — see Temporal.
If you find yourself wanting to tune these, talk to support@quantumbpm.com — we'd rather understand the workload and give you a recipe than have you guess.