Configuration file reference

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} — default when 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 :-default support. 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 #

KeyDefaultDescription
log.levelinfo,openraft=warn,actix_server=warnGlobal 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 #

KeyDefaultDescription
path.datadataBase data directory; node working dirs live under <path.data>/<cluster.name>/nodes/<node.id>.
path.loglogBase log directory.

api #

The HTTP API server.

KeyDefaultDescription
api.network.binding127.0.0.1:28000Listen 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_portfalseAuto-shift to the next free port when binding is occupied. When false, an occupied binding aborts startup with an error.
api.loggingfalseLog HTTP requests.
api.compresstrueCompress responses (gzip/br/deflate via Accept-Encoding).
api.max_payload_bytes104857600Maximum accepted request body size (100 MiB, mirrors ES http.max_content_length).
api.keep_alive_in_secs60HTTP keep-alive.
api.workersCPU countActix worker threads.
api.max_backlog1024Listen backlog.
api.max_connections25000Concurrent connection cap.
api.worker_max_blocking_threads512Blocking thread pool per worker.
api.client_request_timeout5000Client body/expect timeouts, in ms.
api.shutdown_timeout_in_secs5Graceful drain window on shutdown (0 = immediate).

cluster and region #

KeyDefaultDescription
cluster.namepizzaCluster name — nodes sharing a data dir layout and cluster name belong together.
cluster.raft.append_entries_rpc_timeout0Client-side deadline (ms) for append_entries RPCs; 0 keeps the legacy deadline (the heartbeat cadence). Raise on WAN links.
cluster.raft.election_timeout_min299Lower bound of the election timeout window (ms).
cluster.raft.election_timeout_max300Upper bound of the election timeout window (ms).
cluster.raft.install_snapshot_timeout200Deadline (ms) per snapshot segment send/install.
region.namepizza_regionRegion 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 #

KeyDefaultDescription
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 #

KeyDefaultDescription
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 #

KeyDefaultDescription
node.idgeneratedStable node identity; persisted in the working dir after first start.
node.namegeneratedHuman-readable name.
node.network.binding127.0.0.1:38000Listen 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_portfalseAuto-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_entries1024Engine entry budget per runtime.
node.recovery_concurrency2Max concurrent shard recoveries (restart replay + peer pull).
node.flush_concurrency2Max concurrent manual epoch flushes (env override: PIZZA_FLUSH_CONCURRENCY).
node.instance_prefixpizzaRaft instance prefix.
node.snapshot_per_events500Raft snapshot cadence (applied events).
node.search.max_concurrent64Per-node FAST-lane search cap (runtime-tunable).
node.search.heavy_concurrency8Per-node HEAVY-lane search cap (runtime-tunable).
node.search.max_per_shard16Serving-side cap on searches in flight against one shard copy.
node.search.slow_threshold_ms500Search slowlog threshold (runtime-tunable).
node.search.default_timeout_ms30000Cooperative 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_ms30000Per-request timeout for embedding and chat calls.
node.embedding.max_batch_texts64Texts 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 #

KeyDefaultDescription
storage.compressionUNCOMPRESSEDSegment file compression (case-sensitive): UNCOMPRESSED, SNAPPY, GZIP, LZO, BROTLI, LZ4, ZSTD, LZ4_RAW.
memtable.threshold4kMutable-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:

KeyDefaultDescription
wal.local.path<data>/walBase directory for per-shard WAL sub-directories.
wal.local.durabilitybatchedWriter 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_size1024Group commit: flush once this many entries accumulated (batched policy).
wal.local.group_commit_max_delay_ms10Group commit: flush after this many ms (batched policy; 0 disables the time bound).
wal.local.io_uringautoio_uring offload for durable-write fsyncs (Linux). Enabled automatically when the kernel supports it; false forces inline fdatasync.
wal.local.segment_durabilityrequestrequest: 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_epoch8Keep the WAL of this many already-built epochs beyond the last indexed epoch (the _changes replay window).
wal.local.retention_bytes536870912Cap the total on-disk WAL footprint per shard (512 MiB); 0 disables the cap.
wal.local.epoch_freeze_max_bytes16777216Epoch freeze threshold — serialized WAL bytes (16 MiB). Runtime override: PUT /_node/_local/settings/epoch_freeze.
wal.local.epoch_freeze_max_ops160000Epoch freeze threshold — operations per epoch. Runtime override: same API.
wal.local.epoch_flush_after_idle_ticks0Freeze 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_flushtrueFreeze + 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 with retention_epochs must be updated.

wal.kafka:

KeyDefaultDescription
wal.kafka.endpoints—Kafka broker addresses for the Kafka-backed WAL.

inplace #

KeyDefaultDescription
inplace.checkpoint_interval_ms10000Independent .inplace mirror checkpoint cadence, checked on the per-shard maintenance tick (500 ms). 0 restores build-pivot-only checkpoints.
inplace.checkpoint_dirty_blocks0Eager 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).

KeyDefaultDescription
trash.retention_secs86400How long trashed data survives. 0 purges on the next sweeper tick.
trash.orphan_scan_enabledtrueAlso trash orphan directories no live metadata references.

security #

KeyDefaultDescription
security.auth_enabledfalseRequire 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 #

KeyDefaultDescription
max_num_of_instances0Cap on node directories this cluster may use on one host.
allow_multi_instancefalsetrue: 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_detectfalseSkip the working-dir scan; always use node.id from the config.

See Multiple instances on one host.

Calendar September 29, 2026
Edit Edit this page