Configuration file reference #
pizza.yml (the default lookup path, override with -c/--config <file>)
is read once at startup. Unknown keys are rejected — the node refuses
to start on a typo, and on a key that was renamed in an upgrade.
Individual keys can be overridden per launch with
pizza -E <key>=<value> (repeatable; values parse as YAML, e.g.
-E node.network.binding=127.0.0.1:12200).
Secret values #
API keys and tokens do not have to live in the file. Any string value may reference an environment variable, resolved at startup:
node:
embedding:
endpoints:
- name: openai
url: https://api.openai.com/v1/embeddings
api_key: ${OPENAI_API_KEY}
catalog:
join_token: ${JOIN_TOKEN:-} # empty unless the variable is set
${VAR}— the variable’s value; the node refuses to start when it is unset (a mistyped name or an unmounted secret should fail loudly, not serve with an empty key).${VAR:-default}—defaultwhen the variable is unset (${VAR:-}for an empty default).${keystore:NAME}— an entry from the node-local keystore (pizza keystore add NAME), with the same:-defaultsupport. Namespaces are explicit — an env var never silently shadows a keystore entry.$${— a literal${(escape).- Substitution is single-pass: a variable’s value is never rescanned for further references.
Effective precedence: -E CLI values (not substituted) > environment
references > keystore references > values written in the file. Resolved
secrets are redacted from logs and --debug output (<redacted>).
This page is the key catalog. Runtime-tunable behavior lives in the layered settings model — see Region Settings and Node Settings for those APIs.
log
#
| Key | Default | Description |
|---|---|---|
log.level | info,openraft=warn,actix_server=warn | Global log filter: trace/debug/info/warn/error, optionally with target-specific directives separated by comma (openraft and actix_server are demoted to warn out of the box). Also runtime-tunable per node. |
path
#
| Key | Default | Description |
|---|---|---|
path.data | data | Base data directory; node working dirs live under <path.data>/<cluster.name>/nodes/<node.id>. |
path.log | log | Base log directory. |
api
#
The HTTP API server.
| Key | Default | Description |
|---|---|---|
api.network.binding | 127.0.0.1:28000 | Listen address for the REST API. |
api.network.advertise | — | The address peers/clients should use when the node is reachable elsewhere than it binds (NAT, container mapping, proxy). Defaults to binding. |
api.network.skip_occupied_port | false | Auto-shift to the next free port when binding is occupied. When false, an occupied binding aborts startup with an error. |
api.logging | false | Log HTTP requests. |
api.compress | true | Compress responses (gzip/br/deflate via Accept-Encoding). |
api.max_payload_bytes | 104857600 | Maximum accepted request body size (100 MiB, mirrors ES http.max_content_length). |
api.keep_alive_in_secs | 60 | HTTP keep-alive. |
api.workers | CPU count | Actix worker threads. |
api.max_backlog | 1024 | Listen backlog. |
api.max_connections | 25000 | Concurrent connection cap. |
api.worker_max_blocking_threads | 512 | Blocking thread pool per worker. |
api.client_request_timeout | 5000 | Client body/expect timeouts, in ms. |
api.shutdown_timeout_in_secs | 5 | Graceful drain window on shutdown (0 = immediate). |
cluster and region
#
| Key | Default | Description |
|---|---|---|
cluster.name | pizza | Cluster name — nodes sharing a data dir layout and cluster name belong together. |
cluster.raft.append_entries_rpc_timeout | 0 | Client-side deadline (ms) for append_entries RPCs; 0 keeps the legacy deadline (the heartbeat cadence). Raise on WAN links. |
cluster.raft.election_timeout_min | 299 | Lower bound of the election timeout window (ms). |
cluster.raft.election_timeout_max | 300 | Upper bound of the election timeout window (ms). |
cluster.raft.install_snapshot_timeout | 200 | Deadline (ms) per snapshot segment send/install. |
region.name | pizza_region | Region name. |
region.settings | — | Static
region settings set here as nested keys — only settings whose registry name starts with region. (currently region.fault_detection.*) are picked up; keys that don’t match are silently ignored. |
region.fault_detection.follower_check.interval has a built-in default
of 50 ms (the shipped example config sets 70); .threshold defaults
to 5000 ms.
catalog
#
| Key | Default | Description |
|---|---|---|
catalog.seed_hosts | [] | Node RPC addresses to join. Empty: this node forms a single-node region. |
catalog.join_token | — | Dynamic admission token, required once the target node has minted join tokens. |
zone and topology
#
| Key | Default | Description |
|---|---|---|
zone.name | — | Zone label recorded in the region metadata (single-region deployments can leave it unset). |
topology.seed_hosts | — | Reserved for Topology Manager nodes: hosts to join as a Raft learner. |
topology.upstream | — | Reserved: addresses of a higher-level Topology Manager cluster ([127.0.0.1:12300]). |
node
#
| Key | Default | Description |
|---|---|---|
node.id | generated | Stable node identity; persisted in the working dir after first start. |
node.name | generated | Human-readable name. |
node.network.binding | 127.0.0.1:38000 | Listen address for the node RPC (raft, replication). |
node.network.advertise | — | The RPC address other nodes dial; lands in the cluster metadata. Defaults to binding. |
node.network.skip_occupied_port | false | Auto-shift on occupied port. When false, an occupied binding aborts startup with an error. |
node.roles | [] | Role restriction: catalog_manager, topology_manager. |
node.cpus_for_runtime | [] | Cores pinned for engine runtimes. Empty = auto. |
node.cpus_for_helpers | [] | Cores for helper pools (query fan-out, builders, merge). Empty = complement of the runtime cores. |
node.cpus_for_gateway | [] | Cores for HTTP workers and the RPC+Raft service thread. Empty = floating. |
node.max_entries | 1024 | Engine entry budget per runtime. |
node.recovery_concurrency | 2 | Max concurrent shard recoveries (restart replay + peer pull). |
node.flush_concurrency | 2 | Max concurrent manual epoch flushes (env override: PIZZA_FLUSH_CONCURRENCY). |
node.instance_prefix | pizza | Raft instance prefix. |
node.snapshot_per_events | 500 | Raft snapshot cadence (applied events). |
node.search.max_concurrent | 64 | Per-node FAST-lane search cap (runtime-tunable). |
node.search.heavy_concurrency | 8 | Per-node HEAVY-lane search cap (runtime-tunable). |
node.search.max_per_shard | 16 | Serving-side cap on searches in flight against one shard copy. |
node.search.slow_threshold_ms | 500 | Search slowlog threshold (runtime-tunable). |
node.search.default_timeout_ms | 30000 | Cooperative search deadline when the request carries no timeout (runtime-tunable). |
node.embedding.endpoints | [] | External OpenAI-compatible model services (name, url, chat_url, api_key, models, insecure_skip_verify). models entries are model ids, each optionally an object {"id": …, "dims": …, "features": […], "inputs": […]} declaring the output dimensionality, the model’s features — embedding (default) or generation (routable via POST /_chat, which needs the endpoint’s chat_url) — and its input modalities (text, default, or image; “multimodal” is an inputs list beyond text). A model id routes to the endpoint listing it as an embedding model; a single configured endpoint serves every model (ad-hoc /_embedding routing — schema declarations are strict, see
AI Services). Powers server-side inference: schema-driven write-time vector derivation, text vector queries, the semantic query, the /_embedding API, and the /_chat generation facade. |
node.embedding.default_endpoint | — | Endpoint name serving model ids no endpoint lists. |
node.embedding.timeout_ms | 30000 | Per-request timeout for embedding and chat calls. |
node.embedding.max_batch_texts | 64 | Texts per embedding request — larger batches split. |
The embedding registry is also runtime-manageable — the console’s
AI Services page or the
AI Services API
(/_node/_local/ai_services) edits services without a restart
(changes persist to <path.data>/ai_services.json, 0600; API keys are
write-only and answered masked). The yml section above is the boot-time
baseline; DELETE /_node/_local/ai_services reverts to it.
storage and memtable
#
| Key | Default | Description |
|---|---|---|
storage.compression | UNCOMPRESSED | Segment file compression (case-sensitive): UNCOMPRESSED, SNAPPY, GZIP, LZO, BROTLI, LZ4, ZSTD, LZ4_RAW. |
memtable.threshold | 4k | Mutable-layer size threshold before flush: <n>k / <n>K (KiB) or <n>m / <n>M (MiB). |
wal
#
The WAL is local-file based by default; a Kafka-backed WAL is available
under wal.kafka.
wal.local:
| Key | Default | Description |
|---|---|---|
wal.local.path | <data>/wal | Base directory for per-shard WAL sub-directories. |
wal.local.durability | batched | Writer WAL durability: strict (fsync per append; alias strict_per_write), batched (group commit by size/timeout), async (never fsync on the hot path). An unrecognized string falls back to batched. |
wal.local.group_commit_batch_size | 1024 | Group commit: flush once this many entries accumulated (batched policy). |
wal.local.group_commit_max_delay_ms | 10 | Group commit: flush after this many ms (batched policy; 0 disables the time bound). |
wal.local.io_uring | auto | io_uring offload for durable-write fsyncs (Linux). Enabled automatically when the kernel supports it; false forces inline fdatasync. |
wal.local.segment_durability | request | request: fsync every built .fire segment before the WAL entries it supersedes are purged (full crash safety). async: skip the per-segment fsync — faster ingest, but a crash may lose segments whose WAL is already purged. |
wal.local.retention_epoch | 8 | Keep the WAL of this many already-built epochs beyond the last indexed epoch (the _changes replay window). |
wal.local.retention_bytes | 536870912 | Cap the total on-disk WAL footprint per shard (512 MiB); 0 disables the cap. |
wal.local.epoch_freeze_max_bytes | 16777216 | Epoch freeze threshold — serialized WAL bytes (16 MiB). Runtime override: PUT /_node/_local/settings/epoch_freeze. |
wal.local.epoch_freeze_max_ops | 160000 | Epoch freeze threshold — operations per epoch. Runtime override: same API. |
wal.local.epoch_flush_after_idle_ticks | 0 | Freeze the active epoch after this many idle maintenance ticks (500 ms each). Disabled by default — epoch cutting is purely size-based. |
wal.local.recovery_tail_flush | true | Freeze + build the WAL-replay tail left in the active epoch on the first maintenance tick after a restart (or follower-promotion replay), instead of holding it in the mutable heap until a size threshold that may never come. false restores the keep-in-memory behavior; env PIZZA_RECOVERY_TAIL_FLUSH=0/=1 beats this key. |
Upgrade note: the retention key was renamed
retention_epochs→retention_epoch. Unknown keys abort startup, so an old config withretention_epochsmust be updated.
wal.kafka:
| Key | Default | Description |
|---|---|---|
wal.kafka.endpoints | — | Kafka broker addresses for the Kafka-backed WAL. |
inplace
#
| Key | Default | Description |
|---|---|---|
inplace.checkpoint_interval_ms | 10000 | Independent .inplace mirror checkpoint cadence, checked on the per-shard maintenance tick (500 ms). 0 restores build-pivot-only checkpoints. |
inplace.checkpoint_dirty_blocks | 0 | Eager checkpoint trigger: flush once this many column blocks are dirty. 0 = disabled. |
trash
#
Deleted data is moved to <data>/trash/ first and physically deleted by
a background sweeper. Runtime-tunable under the names
node.trash.retention_secs / node.trash.orphan_scan_enabled (see
Node Settings).
| Key | Default | Description |
|---|---|---|
trash.retention_secs | 86400 | How long trashed data survives. 0 purges on the next sweeper tick. |
trash.orphan_scan_enabled | true | Also trash orphan directories no live metadata references. |
security
#
| Key | Default | Description |
|---|---|---|
security.auth_enabled | false | Require an API key on the data plane + management APIs. |
security.bootstrap_key | — | One-shot platform_admin key minted at startup. Unset with auth on: a random login token is generated and printed at startup. "" opts out entirely. |
security.keys | [] | Statically declared keys (SHA-256 hex hashes), each with id, hash, tenant, user, role (platform_admin | namespace_admin | read_write | read_only). |
See Security for the full authentication and role model.
Instance detection #
| Key | Default | Description |
|---|---|---|
max_num_of_instances | 0 | Cap on node directories this cluster may use on one host. |
allow_multi_instance | false | true: a node may start a fresh identity when all existing dirs are locked. false: adopt the locked identity and fail fast on drift. |
skip_instance_detect | false | Skip the working-dir scan; always use node.id from the config. |