Skip to content

Latest commit

 

History

History
264 lines (224 loc) · 40.6 KB

settings.md

File metadata and controls

264 lines (224 loc) · 40.6 KB

Engine settings reference

Every environment variable and configuration key the Engine reads, with the default the code applies, what the value bounds, and where it applies. The tables are generated by reading the source, not the deployment: when a default is derived from the environment (the container's cgroup limit, the cores the process may use) the derivation is stated, and the AKS column gives the value the qualification cluster runs with, from the chart (infra/helm/kaveon-engine, which since 2026-09-17 renders every memory and exchange budget per role, so helm upgrade reproduces the StatefulSets that were first changed with kubectl set env). "Not set" means the default applies. Anything this page could not establish from the source is marked as such rather than guessed. Checked against config.rs and main.rs on 2026-09-17: every variable the server reads is listed; the CLI's own variables are in the last section.

Precedence: an environment variable overrides the matching key in the configuration file (/etc/kaveon/config.toml, or the path given as the first argument to kaveon-server). Sizes are bytes unless the unit column says otherwise; there is no suffix parsing (3221225472, not 3 GiB).

Sources: engine/crates/server/src/config.rs (the server configuration), engine/crates/exec/src/local_parallel.rs and partitioned.rs (operator settings read at execution time), engine/crates/storage/src/adls_reader.rs (scan lanes), engine/crates/server/src/transport.rs (IPC spool), engine/crates/core/src/process_memory.rs (the process guard).

Memory

Name Config key Default Unit What it bounds Applies to AKS qualification value
KAVEON_QUERY_MEMORY_LIMIT_BYTES memory.query_limit_bytes 536870912 (512 MiB); on a process with a memory limit, capped at the admission limit bytes One query memory pool: the statement on the coordinator, one task of the query on a worker. Every operator reservation answers to it. Must be greater than zero and at most the admission limit. coordinator (per statement), worker (per task) coordinator 536870912 (512 MiB), workers 3221225472 (3 GiB); chart values coordinator.memory.queryLimitBytes / workers.memory.queryLimitBytes
KAVEON_MEMORY_ADMISSION_LIMIT_BYTES memory.admission_limit_bytes 4294967296 (4 GiB) when the process is unlimited; on a limited process and neither the variable nor the key set: process limit minus the headroom (below) bytes The sum of admitted query pools on the node. A statement or task whose pool does not fit on arrival waits in the admission queue (next two rows). Cannot exceed the process limit. coordinator, worker coordinator 2147483648 (2 GiB), workers 4294967296 (4 GiB); chart values <role>.memory.admissionLimitBytes
KAVEON_MEMORY_ADMISSION_QUEUE memory.admission_queue 64 statements (coordinator) or tasks (worker) How many arrivals may wait for admission at once, in arrival order. The head of the queue is admitted first and only when its whole pool fits; nothing behind it is admitted ahead of it, and nothing arriving is admitted while anyone is queued. An arrival that finds the queue full is refused at once: HTTP 429 MEMORY_ADMISSION_REJECTED on the coordinator, a task failure the coordinator retries on a worker. 0 is the pre-2026-09-17 behaviour: whatever does not fit on arrival is refused on arrival. The default is the cap on open waiting requests, not on latency: the wait below bounds latency. coordinator, worker not set (default 64; not yet measured on the cluster)
KAVEON_MEMORY_ADMISSION_WAIT_SECONDS memory.admission_wait_seconds 60 seconds How long a statement waits in the coordinator's admission queue before it is refused with HTTP 429 MEMORY_ADMISSION_REJECTED (the refusal carries admission_wait_ms; the statement stays in the history as FAILED with its wait). Must be positive when the queue is on. The ceiling of the per-request admission_wait_seconds. Workers do not apply it: a queued task waits until its query is cancelled or the coordinator's task timeout ends it. coordinator not set (default 60)
KAVEON_PROCESS_MEMORY_LIMIT_BYTES none the container's cgroup limit (/sys/fs/cgroup/memory.max, then memory/memory.limit_in_bytes); max or the v1 unlimited sentinel means no limit; 0 disables the guard bytes The process guard: reservations fail closed when live allocated bytes plus the request would leave less than the headroom under this limit. Headroom is max(15% of the limit, 256 MiB). coordinator, worker not set: cgroup limits apply, 4 GiB on the coordinator and 6 GiB on the workers (chart resource limits)
KAVEON_HASH_ADAPTIVE_BYTES none min(query limit / 16, 64 MiB), then capped at query limit / 4 whatever is configured bytes How much a hash aggregate or join may grow in memory before the adaptive partitioned operator starts spilling its partitions. Read per operator at execution time. worker (task operators), coordinator (node-local operators) not set
KAVEON_ADAPTIVE_PARTIAL_AGGREGATION none on on / off Whether a grouped partial aggregate judges its own reduction: after each flush round of at least 100 000 rows, a round that made a group for 0.8 or more of its rows switches the partial to passing rows through as their own partial rows (per-row states, the same encoding) for four rounds' worth, then eight, judging an aggregating round in between; a round that reduces resumes aggregating. off aggregates every row as before. The thresholds are constants (ADAPTIVE_PARTIAL_MIN_ROWS, ADAPTIVE_PARTIAL_THRESHOLD in partitioned.rs), justified there from the measured probe and encode costs. Read per operator at execution time; the task metrics report aggregate_partial_mode, aggregate_partial_passthrough_rows and aggregate_partial_reduction. worker (task partials), coordinator (node-local partials) not set

Parallelism

Name Config key Default Unit What it bounds Applies to AKS qualification value
KAVEON_LOCAL_PARALLELISM none min(available cores, 4); whatever is set is then capped at 16 and at the available cores threads Threads one task runs for a grouped partial aggregate, a DISTINCT, and the final merge; also the node-local aggregate on the coordinator. Rows are hash-partitioned by key across the threads so memory is one aggregator's. Must be a positive integer. worker (per task), coordinator (node-local and final stages) not set; the chart does not render it, so the default applies: 3 on a worker (CPU limit 3) and 2 on the coordinator (CPU limit 2). The 2026-09-11 Log row says the chart carried explicit values; the chart in this tree does not, so whether the live StatefulSets carry an explicit value is not established here.
KAVEON_SCAN_PARALLELISM none min(available cores, 4); 1 restores the single sequential decoder decoder lanes Row-group decoder lanes per scan of a large ADLS object (adls_reader), and the worker threads of the reader's runtime. Values below 1 or unparsable fall back to the default. worker (scans), coordinator (node-local scans) not set (default lanes: 3 on a worker)

available cores is std::thread::available_parallelism(), which honours the container's CPU quota on Linux.

Spill

Name Config key Default Unit What it bounds Applies to AKS qualification value
KAVEON_HASH_SPILL_MODE disk unset or any other value: the spill paths behave as KAVEON_HASH_SPILL_ROOT describes memory, memory-only Chooses the adaptive in-memory partial aggregate instead of writing partitions to disk. It flushes bounded rounds and passes near-unique input straight through, so no binary state is written per row — faster where memory is ample, which is why qualification runs and single-node deployments use it. Disk spill stays the default because a constrained production node needs the bounded-memory guarantee more than the speed. Read before KAVEON_HASH_SPILL_ROOT, so a memory mode disables spill whether or not a root is set. worker, coordinator unset (disk spill)
KAVEON_HASH_SPILL_ROOT none unset: memory-only execution, no spill directory path Where the partitioned hash aggregate, join, sort and TopN spill their partitions and runs. Setting it turns the spill paths on for every query on the node; it must not be empty. worker, coordinator /tmp/spill (chart, both roles)
KAVEON_HASH_SPILL_BYTES none 10737418240 (10 GiB) bytes One query's spill budget across all its spilling operators on this node (a SpillManager shared through the query pool). Not a process-wide quota. worker, coordinator 4294967296 (4 GiB, chart spillDiskLimitBytes)
KAVEON_HASH_SPILL_PARTITIONS none 16 partitions Spill partition count per partitioned operator; 1 to 256. For a join it is the fan-out of every repartitioning level: a partition whose build is still refused is split this many ways again, to three levels (MAX_JOIN_SPILL_DEPTH), after which the join fails closed. worker, coordinator not set
KAVEON_SPILL_COMPRESSION none unset: spill runs are written uncompressed lz4 / lz4_frame / true / 1; any other value is off Compresses the Arrow IPC spill runs the hash aggregate, join, sort and TopN write, with LZ4 frame. Opt-in while it is qualified: it can cut the disk traffic of a high-cardinality grouped-state run, and it adds CPU to every batch written and read back, so it has to be measured against the uncompressed default rather than assumed. Read once when a spill writer is opened. worker, coordinator not set (uncompressed)

Exchange

Name Config key Default Unit What it bounds Applies to AKS qualification value
KAVEON_COORDINATOR_EXCHANGE_SPOOL none true boolean (true/false) Whether the coordinator keeps a disk exchange store and acts as the hub for exchange partitions. Off, workers hold payloads in memory unless the worker spool is on. coordinator false (chart value coordinator.exchange.spool)
KAVEON_WORKER_EXCHANGE_SPOOL none false boolean Whether workers keep the exchange partitions addressed to them on their own disk, so producers upload straight to the consuming worker and the coordinator relays nothing. worker true (chart value workers.exchange.spool)
KAVEON_EXCHANGE_SPOOL_ROOT none the system temporary directory directory path Root of the disk exchange store on whichever role spools. coordinator or worker, whichever spools /state/exchange on both roles (chart)
KAVEON_EXCHANGE_RECLAIM_ON_START none false boolean (true/false, 1/0, on/off) On a dedicated spool root, remove exchange directories left by the previous process before accepting traffic. Enable this for a single-owner coordinator or worker volume; do not enable it on a root shared by multiple live Engine processes. coordinator or worker, whichever spools true in the Helm chart
KAVEON_EXCHANGE_DISK_LIMIT_BYTES none 10737418240 (10 GiB) bytes The disk exchange store's total on the node, across queries. Must be positive. coordinator or worker, whichever spools workers 8589934592 (8 GiB); coordinator 25769803776 (24 GiB, kept sized for its 32 GiB PVC although its spool is off); chart values <role>.exchange.diskLimitBytes
KAVEON_EXCHANGE_QUERY_DISK_LIMIT_BYTES none 8589934592 (8 GiB) bytes One query's share of the disk exchange store. Must be positive and is expected to be at most the store's total. coordinator or worker, whichever spools workers 6442450944 (6 GiB); coordinator 17179869184 (16 GiB); chart values <role>.exchange.queryDiskLimitBytes
KAVEON_IPC_SPOOL_ROOT none the system temporary directory directory path Where a consumer spools a received Arrow IPC payload before decoding it (transport.rs). The directory must exist. worker (final and join stages), coordinator (result collection) /state on the workers (chart); the coordinator uses the default
KAVEON_EXCHANGE_TOKEN exchange.token none (required for a cluster) bearer token The credential workers and the coordinator present on /v1/task, /v1/exchange/*, /v1/node/heartbeat and /v1/internal/*. Must be nonempty and distinct from every other token. coordinator, worker from the kaveon-engine-auth secret
KAVEON_STAGE_RETRY_LIMIT none 2 re-executions per stage per query How many times one stage's finished output may be produced again for one query because a worker holding its consumers' exchange spools was lost. A lost worker's tasks move to survivors and the producers of every consumer partition whose spool was on it run again as the next attempt (down to the scans when their own inputs were released); beyond the limit the query fails, naming the lost worker and the stage. 0 keeps task retry and refuses stage re-execution. coordinator not set (default 2; not yet measured on the cluster)

Fixed exchange limits that are not settings: a streamed output partition is at most 8 GiB in 4 MiB chunks (2048 chunks); a received payload is at most 8 GiB; the process-wide IPC spool holds at most 12 GiB at once; a task is attempted at most 3 times (failures of its own; an attempt created by a worker loss is not one).

Storage, catalogs and scans

Name Config key Default Unit What it bounds Applies to AKS qualification value
KAVEON_DATA_DIR storage.data_dir none directory path A local directory whose Parquet files, directories of Parquet files and Delta tables bootstrap the kaveon catalog on first start. coordinator, worker not set
KAVEON_CATALOG_DIR storage.catalog_dir none directory path A directory of <name>.toml catalog files bootstrapped on first start. coordinator, worker not set
KAVEON_CATALOG_DATABASE_PATH storage.catalog_database_path, catalog.database_path kaveon-catalog.db in the working directory file path The durable catalog store (SQLite). Its parent directory is created. coordinator, worker /state/catalog/kaveon-catalog.db
KAVEON_CATALOG_ADMIN_TOKEN catalog.admin_token none bearer token The service credential confined to /v1/catalog/* definition writes. Nonempty and distinct when set. coordinator from the kaveon-engine-auth secret
KAVEON_STATISTICS_AUTO_REFRESH none true boolean Whether the coordinator refreshes a table's statistics in the background when planning observes a source version newer than the one on record (files added to a full document folded in; a removal or a metadata-only document recomputed at the document's depth; one refresh per table at a time). Off, statistics change only through ANALYZE; a stale record still costs a plan and never answers a statement. The same knob governs the cube's refresh (added files folded in; a removal re-derived from the per-file partials, or rebuilt when a distinct count is declared). coordinator not set (default)
KAVEON_CUBE_MAX_CELLS none 1000000 positive integer The most cells a table's cube may hold: a declared shape whose planned cube (the caps' products over its groupings) exceeds it is refused, and a build or refresh that exceeds it fails. The encoded document is bounded with it, at 1 MiB plus 256 bytes per cell of the limit, and the per-file partials at eight times the limit in cells. coordinator not set (default)
KAVEON_RAW_GROUP_EXCHANGE none false 1, true, on to enable Partitions a grouped aggregate's exchange by the group columns themselves rather than by the encoded aggregate-state key. Read by both the planner and the fragment executor, so it must hold the same value on the coordinator and every worker. coordinator, worker not set (default)
KAVEON_COALESCE_PARTIAL_ROWS none unset rows Opt-in Arrow batch coalescing for multi-key, high-cardinality pass-through partials. Several exact pass-through batches are concatenated before exchange consumption; one-key pass-throughs do not use it. Values below 2 or invalid values disable it. worker unset; qualify per workload
KAVEON_PARTIAL_ROUND_ROBIN none unset 1, true, on to enable Opt-in round-robin slicing for multi-key partial aggregates. Local lanes merge duplicate keys at the final stage, avoiding the source-side hash partition and Arrow take copies. Other operators are unchanged. worker unset; qualify per workload
KAVEON_DIRECT_GROUPED_EXCHANGE none unset (off) exactly 1 enables it; any other value is off Routes a grouped partial's canonical Binary group_keys frame straight through the exchange. The final merge's equality parser reads the same bytes, so both the Arrow row conversion and the later ThreadSelector hash are skipped. Applies only where the source is threaded and the partial exposes a Binary group_keys field; the established text path remains the fallback for every other caller. worker unset (off); qualify per workload
KAVEON_ZERO_COPY_SELECTED_MERGE none unset (off) exactly 1 enables it; any other value is off Lets a selected final merge take its input without copying, on the HybridFinalMerge path that already carries a worker selection. Only reached when a selection is present. worker unset (off); qualify per workload
KAVEON_SCAN_PARTITIONS_PER_WORKER none 1 1-16 How many scan partitions are scheduled per compatible worker. A single large Parquet file is one task at the default, so one worker decodes all of it however many are in the cluster; above one, the file is split by row groups and its decode and partial aggregation stay concurrent. Values outside the range fall back to the default. coordinator not set (default)
KAVEON_EXCHANGE_PARTITIONS none the worker count 1-64 Destination partitions for a distributed aggregate's exchange. Scan stages may deliberately carry more tasks than the merge stage, so raising scan parallelism does not multiply the grouped state copied across the exchange. Defaults to the worker count, which preserves the original graph shape. Values outside the range fall back to that default. coordinator not set (default)
KAVEON_EXCHANGE_COMPRESSION none disabled lz4, lz4_frame, 1, true Enables LZ4-framed Arrow IPC for exchange payloads. This reduces transfer and spool volume on wide grouped states at the cost of CPU; leave unset for same-host low-latency profiles until qualified. coordinator, worker unset
KAVEON_USE_UTF8_VIEW none unset set to any value to enable Reads Parquet string columns as Arrow Utf8View rather than Utf8. Presence is what counts, not the value. worker, coordinator not set
KAVEON_FRAGMENT_LISTING_MAX_FILES none 10000 files The largest directory-table listing the coordinator carries inside the fragments (the pruned file set and per-task assignment, wire version 6); over it the fragment carries the listing's digest only and each task lists, prunes and verifies the digest itself. coordinator not set
KAVEON_DIFF_ONLY none unset differential-case name Test-harness selector used by the server differential corpus to run one named case instead of the full sweep. It is intended for focused local qualification and is not a runtime execution setting. test harness only not set
KAVEON_PRODUCT_TRANSACTIONS_ENABLED product_transactions.enabled false boolean Whether the coordinator opens the product transaction store (native catalog commits, DML). Coordinator only. coordinator chart value productTransactions.enabled; enabled on the live coordinator per the 2026-09-10 Codex response
KAVEON_PRODUCT_STORAGE_MODE product_transactions.storage_mode adls adls or local Where the product store commits. coordinator adls
KAVEON_PRODUCT_ADLS_ACCOUNT product_transactions.account empty (required when enabled with adls) account name The ADLS Gen2 account of the product store. coordinator the qualification account (kvtesticmwwliihpppo since the 2026-09-14 move to westus2; kvtestegmf6oweugsno was the eastus account), chart value productTransactions.account
KAVEON_PRODUCT_ADLS_CONTAINER product_transactions.container empty (required when enabled with adls) container name The container of the product store. coordinator product-transactions
KAVEON_PRODUCT_ADLS_PREFIX product_transactions.prefix kaveon/product-catalog object prefix The prefix under which the product store commits. Must be nonempty when enabled. coordinator kaveon/product-catalog
KAVEON_PRODUCT_LOCAL_PATH product_transactions.local_path /var/lib/kaveon/product-transactions directory path The product store's directory in local mode. coordinator not applicable
KAVEON_AZURITE_CONTAINER none kaveon-product container name Overrides the blob container used by the ignored Azurite conditional-commit contract test. Test-only; production ADLS commits use KAVEON_PRODUCT_ADLS_CONTAINER. storage test harness not applicable
KAVEON_LATE_MATERIALISATION none auto auto, always, never (on/off accepted) Whether a scan over object storage runs the evaluable part of its predicate inside the Parquet decoder as a row filter (the predicate's columns decoded first, the rest of the projection only for the rows that survive; pages the selection never touches are skipped when the file carries an offset index). auto applies it when the remaining projection holds at least 4x the compressed bytes of the predicate's columns, or when the object is held in the full-object cache; otherwise the decoder lanes filter decoded batches. always and never override the ratio. Local Parquet files always use the row filter. Unrecognised values are auto. worker, coordinator not set
AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_FEDERATED_TOKEN_FILE, AZURE_AUTHORITY_HOST none none strings Workload identity for the product store's ADLS commits (adls_commit.rs) and, through the object store's from_env, for ADLS scans. Set by the AKS workload identity webhook. coordinator (commits), worker and coordinator (scans) injected by the kaveon-engine service account

Fixed storage limits that are not settings: decoder lanes are capped at 4 per scan; the late-materialisation byte ratio is 4; the full-object cache admits objects up to 64 MiB and holds 256 MiB per process; the decoded-batch cache holds 256 MiB per process; a Delta log replay reads at most 64 MiB of commit JSON; Iceberg metadata is capped at 64 MiB.

Service and security

Name Config key Default Unit What it bounds Applies to AKS qualification value
(first argument) file path /etc/kaveon/config.toml path The configuration file. Missing is not an error; every key then comes from the environment or the default. coordinator, worker not used; everything is environment
KAVEON_NODE_ID node.id a random UUID per start string The node's identity in the cluster and in task ownership. coordinator, worker the pod name
KAVEON_ENVIRONMENT node.environment production string The environment name reported on /v1/cluster and every query record. coordinator, worker aks-test
KAVEON_COORDINATOR node.coordinator true boolean The role: true serves statements, false executes tasks and heartbeats to the coordinator. both true on the coordinator StatefulSet, false on the workers
KAVEON_HTTP_PORT http.port 8080 port The listening port. both 8080
KAVEON_BIND_HOST none 127.0.0.1 IP address The listening address. A non-loopback address requires TLS, KAVEON_TLS_PROXY_BOUNDARY=true, or insecure development mode. both 0.0.0.0
KAVEON_DISCOVERY_URI discovery.uri http://localhost:8080 URI Where a worker finds the coordinator for heartbeats and where the coordinator publishes catalog snapshots. worker the coordinator service URI over HTTPS
KAVEON_ADVERTISED_URI discovery.advertised_uri none: http(s)://127.0.0.1:<port> URI The address other nodes use to reach this one (task and exchange traffic). both the pod's DNS name
KAVEON_TLS_CERT_PATH, KAVEON_TLS_KEY_PATH none none file paths Serve HTTPS; both or neither. both /etc/kaveon/tls/tls.crt, /etc/kaveon/tls/tls.key
KAVEON_TLS_PROXY_BOUNDARY none unset true Allows a non-loopback plaintext bind behind a network-isolated TLS proxy. both not set
KAVEON_INSECURE_DEVELOPMENT security.insecure_development (JSON) false boolean Development mode: plaintext external binding and relaxed credential checks. Never set in a deployment. both not set
KAVEON_CONFIG_ENV_FALLBACK none false boolean If the mounted config file is malformed, ignore it and load defaults plus environment settings. Requires KAVEON_INSECURE_DEVELOPMENT=true or KAVEON_TLS_PROXY_BOUNDARY=true; intended for legacy ACA mounts only. both set only during controlled ACA compatibility rollout
KAVEON_SECURITY_JSON the whole SecurityConfig none (no principals: nothing can submit) JSON (TOML accepted only for legacy fallback) principals (token, principal, role: reader, analyst, admin), bridge_token, entra, studio_url, insecure_development, and the legacy resource_groups list (name, principals with one optional * catch-all, max_running, max_queued, queue_timeout_ms), still accepted and translated into resource groups at start when nothing else configures them (see Governance). Validated on start; tokens must be nonempty and distinct. A malformed value is fatal unless the explicit config environment fallback is enabled with insecure development; that emergency path discards the malformed document and must not be used for production authentication. coordinator (statements), worker (its own credentials) from the kaveon-engine-auth secret, key security.json
KAVEON_STUDIO_URL security.studio_url none URL The Studio origin allowed to use the Engine UI's sign-in. coordinator chart value studioUrl
KAVEON_PRINCIPAL_QUERY_LIMIT none 4 statements The default resource group's max_concurrent when no resource-group configuration names one: statements of the default group running at once on the coordinator. Kept as the alias; before 2026-09-19 it bounded each principal separately. Must be positive. coordinator not set
KAVEON_STATE_DIR node.state_dir the directory of the catalog store (KAVEON_CATALOG_DATABASE_PATH) directory path Where the coordinator keeps what must survive a restart and is not the catalog store: the durable copy of a runtime resource-group replacement (resource-groups.json) and the audit ledger (audit/). coordinator not set: /state/catalog
KAVEON_AUDIT_DIR audit.dir <state dir>/audit directory path Where the audit ledger keeps its JSONL segments and the catalog cursor (Governance). coordinator not set: /state/catalog/audit
KAVEON_AUDIT_RETENTION_DAYS audit.retention_days 90 days A ledger segment is removed once every record in it is older than this; 0 turns the ledger off. coordinator not set
KAVEON_AUDIT_SEGMENT_BYTES audit.segment_bytes 67108864 (64 MiB) bytes The size at which a ledger segment is closed and the next started; at least 1 MiB. coordinator not set
KAVEON_RESOURCE_GROUPS [resource_groups] section ([[resource_groups.groups]], [[resource_groups.selectors]], [resource_groups.demo]) none: the durable runtime copy, the section, the legacy list, else one built-in default group file path (JSON, or TOML by extension) The resource groups and selectors (groups, selectors, demo at the top level; the keys and bounds are in Governance). Validated on start; a group over the admission limit, without a default, a selector naming an unknown group, or a rate without demo.enabled refuses to start. PUT /v1/admin/resource-groups writes back to this file. coordinator not set; the chart renders it from resourceGroups when that block is enabled

The demo posture

One switch on each side, both off by default so a self-hosted install is unaffected. Neither is read by the Engine as an environment variable.

Where Key Default What it does
API KAVEON_DEMO_MODE (chart value api.demoMode) false Every mutating platform route — datasets, charts, dashboards, saved queries, catalog registration, DLM curation, settings — answers 403 demo_read_only for any role below Admin; viewing stays; per-user preferences (favorites, pins, theme, recents, the user's own history) stay; SQL Lab and the DLM stay, with submitted SQL confined to one read statement (SELECT, WITH, SHOW, DESCRIBE, EXPLAIN — DDL, DML, CALL, ANALYZE, OPTIMIZE and SET SESSION are refused with the same code). One application-level dependency in api/main.py.
Engine demo.enabled in the resource-group document (chart value resourceGroups.document.demo.enabled) false Enables a group's rate — the per-principal quota of live statements over a rolling window, admins exempt, counted from the audit ledger so it survives a restart — and GET /v1/quota. Off, a rate is refused at validation. See Governance.

Result cache

Name Config key Default Unit What it bounds Applies to AKS qualification value
KAVEON_RESULT_QUERY_DISK_LIMIT_BYTES none 268435456 (256 MiB) bytes One paged result's disk on the coordinator (result_delivery: paged: the CLI's --paged and the shell's page reads, SQL Lab's streamed statements). A statement whose pages would exceed it fails with query result disk quota exceeded (… MiB); raise KAVEON_RESULT_QUERY_DISK_LIMIT_BYTES on the coordinator, or narrow the result. Must be positive. coordinator not set (default); the local Compose stack sets 2 GiB for its 504M-row lake
KAVEON_RESULT_DISK_LIMIT_BYTES none 1073741824 (1 GiB) bytes Every paged result's disk together, on the coordinator; a page that would exceed it fails the statement naming the setting. Must be at least the query limit. Results expire after the store TTL (below). coordinator not set (default); the local Compose stack sets 4 GiB
KAVEON_RESULT_CACHE_BYTES result_cache.bytes 268435456 (256 MiB); 0 disables the cache bytes The coordinator's budget for complete results of finished statements, evicted least-recently-used by bytes. A result larger than an eighth of the budget is never kept. Workers keep nothing whatever the value. coordinator not set (default)
KAVEON_RESULT_CACHE_TTL_SECONDS result_cache.ttl_seconds 600 seconds How long a cached result may be served. Must be positive when the cache is enabled. coordinator not set (default)

A result is keyed by the statement text (trimmed, whitespace collapsed and letters lowercased outside string literals and quoted identifiers), the catalog and schema, the published catalog snapshot identity, the Delta versions the planner pinned, and the request's time zone. A catalog publish clears every entry; so does a committed product transaction and DELETE /v1/cache (admin). Hits are query records with execution: {mode: "cache", detail: "hit"} and cached_from naming the original query; counters (hits, misses, bytes, entries, evictions, expirations, refused) are on /v1/node and on the coordinator entry of /v1/cluster. Per-request bypass: settings.result_cache = false; every benchmark and qualification script in this repository sends it.

Per-request settings

A statement may lower four of the bounds above for itself, and choose two behaviours (what approximate and use_statistics decide on the knowing path is in The learning engine), through the settings object of POST /v1/statement or leading SET SESSION <key> = <value>; statements in the same request. Nothing can be raised; an unknown key or an out-of-range value is HTTP 400 INVALID_SETTING with the key named. HTTP is stateless and there is no server-side session: a setting lives as long as the statement it arrived with. The query record's settings field shows what a statement set. See the API reference for the request shapes.

Key Bound What it lowers Where it applies
query_memory_limit_bytes 1 to the coordinator's KAVEON_QUERY_MEMORY_LIMIT_BYTES The statement's query memory pool on the coordinator and the admission limit of each of its tasks on the workers (each worker also caps it at its own limit). coordinator, worker
local_parallelism 1 to the coordinator's configured KAVEON_LOCAL_PARALLELISM Aggregator threads for the statement's partial aggregates, DISTINCT and final merges; carried in the task request and capped again by each worker's own value. coordinator, worker
result_cache true or false false bypasses the coordinator's result cache for the statement. coordinator
admission_wait_seconds 0 to the coordinator's KAVEON_MEMORY_ADMISSION_WAIT_SECONDS How long the statement waits for memory admission before HTTP 429; 0 refuses at once when its pool does not fit on arrival (the pre-2026-09-17 behaviour, for a client that prefers to retry itself). Ignored when the node has no queue. coordinator
approximate true or false, default false true lets the planner answer every plain COUNT(DISTINCT col) from a HyperLogLog sketch — computed over the rows, or stored in the table's statistics — exactly as APPROX_COUNT_DISTINCT(col) would, under COUNT's output name; the query record's execution.approximate states the error (1.6 % relative standard error at p = 12). Nothing else is approximated; APPROX_* functions need no setting. See Approximate aggregates. coordinator (planning), worker (the sketch aggregate)
use_statistics true or false, default true false stands every answer from statistics aside: the context path for COUNT(*)/MIN/MAX and the statistics path for APPROX_* are both skipped and the rows are read (APPROX_* computes its sketch over them; exact functions scan as usual). File skipping by the statistics' bounds still applies — pruning, not answering — and statistics still cost a join. execution.detail ends with statistics bypassed when the statistics would otherwise have answered. Every benchmark script sets it beside result_cache = false: a benchmark measures the read path. coordinator

Timeouts and intervals

None of these is a setting today; they are constants in the source, listed so that an operator knows what bounds a run. Changing one is a code change.

Constant Value Where What it bounds
REMOTE_TASK_TIMEOUT 600 s api.rs One task request from the coordinator to a worker. A task that times out is not retried; finishing the query cancels its orphaned tasks on the workers.
HEARTBEAT_INTERVAL 10 s cluster.rs How often a worker heartbeats to the coordinator.
NODE_EXPIRY 30 s cluster.rs A worker with no heartbeat for this long leaves the cluster view.
WORKER_LOSS_MISSED_HEARTBEATS, WORKER_PROBE_TIMEOUT 2 intervals (20 s), 5 s cluster.rs, api.rs When a running query treats a worker as lost: a refused or reset connection to it (the task call or a /v1/node probe after a retryable task failure), or a heartbeat lapsed by two intervals with a probe unanswered within 5 s. A worker that answers the probe is not lost, whatever its task said.
Result store TTL 900 s results.rs How long paged results stay readable.
Disk exchange TTL 900 s disk_exchange.rs How long an exchange partition stays on disk after its query.
Cleanup loop 30 s main.rs How often expired results and exchange partitions are removed and the audit ledger's retention is applied.
Graceful shutdown 30 s main.rs On SIGTERM or Ctrl-C the listener closes, in-flight requests get this long to finish, then the audit ledger drains and the process exits.
Entra JWKS cache 3600 s, refreshed no more than every 60 s, fetched with a 5 s timeout entra.rs The signing keys used to validate Entra bearer tokens.
Resource group max_queue_wait_seconds per group (default 60) resource_groups.rs, api.rs How long a statement waits for its group's slot, its group's share and the node's pool together before HTTP 429; one wait, the shortest of the group's, the node's and the request's.

Other fixed limits: query history keeps 100 records; inline (unpaged) results are capped at 16 MiB; the paged result store writes 4 MiB pages of at most 1000 rows (its per-query and per-process disk are settings, above); the catalog replica a worker downloads is at most 16 MiB; the worker task-reply cache holds 512 MiB per process; the in-memory exchange buffer (when no node spools) holds 512 MiB and 1024 exchanges.

CLI variables

Test harness variables

These variables are consumed only by repository test binaries; the Engine runtime does not read them. They are for reproducing a focused qualification case and must not be set in a deployment.

Name Default What it sets
KAVEON_DIFF_ONLY unset The kaveon-server differential-test case name to run exclusively (for example, correlated_scalar_ordered_offset_limit). Unset runs the complete differential case list.

These are read by the kaveon client (engine/crates/cli/src/args.rs, auth.rs, theme.rs), not by the server; the CLI guide describes them. Each variable has a flag that overrides it; the defaults file (KAVEON_CONFIG) sits between the two: a flag beats the file, the file beats the built-in default.

Name Default What it sets
KAVEON_CONFIG ~/.kaveon_config when it exists The key=value defaults file. Allowed keys: server, catalog, schema, user, source, client-tags, auth, ca-cert, timeout, output-format, output-format-interactive, history-file, editing-mode, pager, theme, width, row-limit. SQL and tokens are refused.
KAVEON_ACCESS_TOKEN none The Engine bearer token for unattended use; --access-token overrides it. Without either, --auth decides (Azure CLI login, Microsoft device sign-in, or none).
KAVEON_CA_CERT none A PEM CA bundle trusted for the coordinator's TLS certificate (--ca-cert). Never applied to Microsoft sign-in.
KAVEON_HISTORY_FILE %APPDATA%\kaveon\history on Windows, ~/.kaveon_history elsewhere The shell's history file (--history-file; --no-history disables it).
KAVEON_PAGER none An external pager for human-readable output when a script or the line-editor fallback prints to a terminal (--pager; empty disables). The shell pages results itself.
KAVEON_API_URL none The Kaveon platform API the shell's .ask sends questions to (--api overrides it); the DLM answers there, not on the Engine.
KAVEON_API_TOKEN none The bearer token .ask presents to the platform API.
NO_COLOR unset Set to anything, the client prints without colour, the same as --theme mono; TERM=dumb and output that is not a terminal have the same effect.

Client flags without a variable, with the value the code applies:

Flag Default Bound What it sets
--timeout 24 h greater than zero; seconds, 30s or 2m The HTTP timeout of one statement request. POST /v1/statement returns when the statement finishes, so this is the longest a statement may take before the client reports a timeout; it does not stop the statement on the coordinator. Metadata calls keep a fixed 30 s. --client-request-timeout is an alias.
--row-limit 1000 1 to 10000 Rows a shell query without a top-level LIMIT shows; .limit changes it in the session. Never applied to -e, -f or piped input.
--theme dark dark, light, mono The accent colour (Kaveon blue, darker on light) or no colour.
--no-header off flag Skips the session header the shell prints after connecting.
--width the terminal's width, else 120 a positive column count The width result tables are fitted to; string columns are narrowed with … to fit.
--paged off flag Scripts fetch results in pages from the coordinator's result store instead of inline, so a result over 16 MiB does not fail.

KAVEON_PARALLEL_SQL_REGRESSION_CHILD is set by one server test to mark its child process and is not a setting.