Environment Variables
Strict parsing. Malformed values FATAL at startup — Relata refuses to boot rather than silently using a wrong default. Removed/renamed vars (e.g.
RELATA_ORG_MODE,RELATA_REQUIRE_ORG,RELATA_ALLOWED_ORIGINS,RELATA_REQUIRE_MTLS,RELATA_MAX_CONNECTIONS) also FATAL — runrelata config --migratewhen upgrading from 1.x.
Config precedence:
env > file > built-in default. File search order: (1)--config <path>flag, (2)RELATA_CONFIGenv var, (3)./relata.toml, (4)~/.relata/relata.toml. Runrelata config --print-templatefor a starter.
Core server
| Variable | Default | Description |
|---|---|---|
RELATA_PROFILE | free | Deployment profile: free (dev/CI — storage-capped, otherwise identical posture to licensed tiers), server (single-node prod), cluster (multi-node). lite was a legacy alias for free and is now rejected. Startup fails (FATAL) on lite or any other value. Auth/TLS/diagnostics posture no longer varies by profile — see RELATA_BEARER_TOKEN, RELATA_OPEN_DEV_ALLOWED, RELATA_PLAINTEXT_OK below. |
RELATA_PORT | 9090 | HTTP API port. |
RELATA_HOST | — | Advertised host name (used for the A2A Agent Card base URL when RELATA_A2A_BASE_URL is unset). Falls back to the bind address. |
RELATA_HTTP_BIND | profile: 127.0.0.1 (free) / 0.0.0.0 (server/cluster) | HTTP bind address for the data plane (/query, /ingest, doors, etc.). This listener no longer serves /admin/* or /platform/* at all — see RELATA_ADMIN_BIND below. Also the input to is_loopback_bind() (127.0.0.1/[::1] prefix, or unset), which gates RELATA_OPEN_DEV_ALLOWED and the RELATA_PLAINTEXT_OK default uniformly across every profile. |
RELATA_ADMIN_BIND | 127.0.0.1:9091 | Bind address for a SECOND, dedicated TcpListener that exclusively serves /admin/* and /platform/* on a loopback-only Zero-Trust control plane. These routes are not mounted on the data-plane listener (RELATA_HTTP_BIND) at all — a request to them there gets a plain 404 (the route doesn't exist), not 401/403, so a remote peer cannot even confirm an admin surface exists. Must resolve to a loopback address (127.0.0.0/8 or ::1) — startup fails (FATAL) otherwise; this is deliberate (loopback is enforced by TCP, not by an HTTP header check), not a bug — widening it would silently reintroduce a network-reachable admin token. Reach it via kubectl port-forward svc/relata 9091:9091 or an mTLS control-plane sidecar in the same pod/network namespace (Kubernetes); on plain Docker/Compose, docker exec into the RelataDB container itself, or share a network namespace (--network container:<relata-container>) — never expose it directly. A separate sidecar container cannot reach it any other way; see Reaching the admin listener from a second container. |
RELATA_BEARER_TOKEN | — | Standing bootstrap secret; also the Authorization: Bearer credential for gRPC, Arrow Flight, pgwire, and the protocol-compat doors (S3/ClickHouse/Neo4j/Redis/MongoDB/Bolt). It never authenticates HTTP data-plane routes (/query, /ingest, /search, …) — on any profile, with no opt-out; only a registry-minted, tenant-scoped token (POST /admin/tokens, or /tokens/self/* for self-service) does. Mandatory on server/cluster (startup fails if unset). On the free profile a dev token may be minted on first run and printed to stderr — set it persistently to reuse it. pgwire is disabled when unset. With no RELATA_BEARER_TOKEN/RELATA_ADMIN_TOKEN and no RELATA_OPEN_DEV_ALLOWED, every data/admin/diagnostics endpoint returns 401 on every profile — cargo run -- serve no longer silently opens anything. |
RELATA_ADMIN_TOKEN | — | Admin-only token for the /admin/* + /platform/* surface (privilege-separated from RELATA_BEARER_TOKEN), gated on the loopbound listener described under RELATA_ADMIN_BIND. Gates: /admin/console (HTML), /admin/tokens, /admin/backup, /admin/backups, /admin/restore, /admin/compact, /admin/rotate-dek, and every /platform/* tenant-lifecycle route. When unset, the entire admin surface returns 401 on free (or, on server/cluster, 503 via admin_surface_guard) — unless RELATA_OPEN_DEV_ALLOWED=true (see below). Browser access: GET /admin/console?token=<RELATA_ADMIN_TOKEN> (the client JS reads ?token= from the URL). Env-only by design: this is a privileged secret and is deliberately not persisted to disk or config — it must be re-supplied on every restart. A restart without it leaves /admin/* and admin-gated features unprovisioned (a client sees this as a degraded/"stub" mode); startup logs a loud Admin surface: UNPROVISIONED warning so the state is never silent. Note: there is an open gap where check_admin_auth falls back to the bearer token when RELATA_ADMIN_TOKEN is unset — set both tokens explicitly in production until this is resolved. |
RELATA_OPEN_DEV_ALLOWED | false | Explicit, uniform-across-every-profile opt-in for the unauthenticated local-dev convenience that used to be a silent RELATA_PROFILE=free special case. When true, AND no RELATA_BEARER_TOKEN/RELATA_ADMIN_TOKEN/registered token is configured, AND RELATA_AUTH_MODE resolves to none (unauthenticated), AND the relevant listener is bound to loopback (data plane: RELATA_HTTP_BIND; admin surface: RELATA_ADMIN_BIND — checked fresh per request, never by profile), every data endpoint (check_auth_with_registry), the admin surface (check_static_admin_auth), and the diagnostics surface (diagnostics_auth_ok) are open with no token. Fail-closed on every axis: unset, a configured credential, a non-None auth mode, or a non-loopback bind all keep the gate closed regardless of profile. Do not set this outside local development. |
RELATA_SECURITY_MODE | strict | strict (default) or open — the master switch over the server/cluster weak-security/dev-mode opt-out flags: RELATA_KMS_LOCAL_DEV, RELATA_UNSAFE_LOCAL_FENCING, and RELATA_GRPC_PLAINTEXT_OK. Under strict, each of those three is refused even when set — RELATA_KMS_LOCAL_DEV/RELATA_UNSAFE_LOCAL_FENCING FATAL at boot naming both required settings, and RELATA_GRPC_PLAINTEXT_OK disables the gRPC/Arrow Flight door instead. Set open alongside whichever individual flag(s) you also need for a genuinely relaxed dev/staging deployment; today's per-flag behavior is unchanged once both are set. Also reported in GET /platform/license's security_posture.security_mode field. Do not set this to open outside local/staging development. |
RELATA_PLAINTEXT_OK | unset (defaults to true only on a loopback bind) | Uniform across every profile, including free. Set true/false explicitly to allow/require TLS termination in front of a plaintext HTTP listener when RELATA_TLS_CERT/RELATA_TLS_KEY are not configured. If unset, the effective default is true when the bind is loopback (RELATA_HTTP_BIND unset or 127.0.0.1/[::1]) and false (TLS required, startup FATALs) otherwise — the same loopback predicate RELATA_OPEN_DEV_ALLOWED uses. There is no longer a free-only unconditional plaintext pass: a free-profile server bound to 0.0.0.0 needs RELATA_TLS_CERT/RELATA_TLS_KEY or an explicit RELATA_PLAINTEXT_OK=true exactly like server/cluster. |
RELATA_DATA_DIR | ./data/relata | Root directory for config files and WAL state. |
RELATA_CONFIG_DIR | — | Override directory for TOML config files (takes priority over RELATA_DATA_DIR). |
RELATA_CONFIG | — | Inline TOML config blob; takes priority over config files. |
RELATA_PUBLIC_URL | — | Externally-visible base URL (used for CORS Allow-Origin and link generation). |
RELATA_URL | http://127.0.0.1:9090 | Base URL the CLI client uses to reach a running relata serve — covers relata import, relata status, relata query, jobs/workflows subcommands, and cluster-admin calls. Falls back to http://127.0.0.1:{RELATA_PORT}. (RELATA_STATUS_URL is a deprecated alias — see the Deprecated section.) |
RELATA_A2A_BASE_URL | — | Explicit base URL advertised in the A2A Agent Card (.well-known/agent.json). Overrides the RELATA_HOST/RELATA_PORT derivation. |
RELATA_DRAIN_TIMEOUT_SECS | 30 | Graceful-shutdown drain timeout. On SIGTERM/Ctrl-C the server first waits (up to this bound) for the ingest queue to reach empty so every acknowledged row is flushed to the WAL before exit. The outcome is observable: an info log ingest drain complete — N rows persisted on success, or a LOUD error ingest drain INCOMPLETE — acked rows may be unpersisted plus a non-zero exit if the timeout fires with acked rows still queued (fail-closed, so an orchestrator never treats an acked-data-loss shutdown as clean). |
RELATA_DEMO_MODE | — | Set true (or 1/yes/on) to enable demo-mode restrictions (read-only ingest, synthetic data). Case-insensitive. Startup fails on unrecognised values. |
RELATA_SHELL_PURPOSE | shell | Default purpose for the relata shell interactive REPL. |
RELATA_ADMIN_URL | derived from RELATA_ADMIN_BIND | CLI-side override for the admin listener's base URL, read by the relata rebuild-index command when the operator already knows the admin listener's externally-reachable address (e.g. the local end of a port-forward/tunnel). Server-side, this variable has no effect. |
RELATA_TOKEN_REGISTRY_MAX | 1000 | Maximum number of dynamic bearer tokens (POST /admin/tokens) that can co-exist at once, across every tenant on this node. A safety rail against unbounded registry growth, not a plan-differentiation limit. POST /admin/tokens past the cap fails with 409 naming both ways to free a slot. 0 falls back to the default (not "allow zero tokens"). |
litewas a silent legacy alias forfree; it is now rejected outright — startup fails (FATAL) ifRELATA_PROFILE=liteis set.
Storage
Relata selects a backend in priority order: in-memory opt-in → S3 → local disk (default).
| Variable | Default | Description |
|---|---|---|
RELATA_IN_MEMORY | — | Set true (or 1/yes/on) to run fully in-memory (dev/CI only — data lost on restart). Case-insensitive. Startup fails on unrecognised values. |
RELATA_LOCAL_DATA_DIR | — | Explicit local-disk path for the object store. When unset, falls back to RELATA_DATA_DIR/objects. |
AWS_ENDPOINT_URL | — | S3-compatible endpoint (AWS S3, R2, GCS, self-hosted). When set, S3 takes priority over local disk. |
AWS_S3_BUCKET | relata | S3 bucket name. |
AWS_ACCESS_KEY_ID | — | S3 access key. |
AWS_SECRET_ACCESS_KEY | — | S3 secret key. |
AWS_REGION | us-east-1 | AWS region (S3 path, KMS). |
RELATA_DURABILITY | s3 | Per-backend WAL recovery posture: s3 (strong), r2 (eventual on failure), s3compat, azure. |
RELATA_ALLOW_HTTP_OBJECT_STORE | — | Set true to silence the plaintext-http:// object-store warning (local S3-compatible dev). Credentials/data travel unencrypted. |
RELATA_STORE_MAX_INDEX_MB | — (adaptive) | Cap on per-store index RAM in MiB. When unset, derived from detected RAM (index ≈11% of the ~75% pool). 0 = unbounded. |
RELATA_TEMPORAL_INDEX_MAX_ENTRIES | 4000000 | Cap on Table's per-entity bi-temporal version-chain index (version_index), in entries per object type. Past the cap, the index stops growing and is marked incomplete — AS OF reads fall back to an exact full scan for that type rather than trusting a truncated index. |
RELATA_WAL_SYNC | interval | Process-global WAL fsync mode. always (fsync on every flush boundary, RPO≈0) | interval (default — batched fsync every ~10 ms, RPO≈10 ms) | off (page-cache only — faster, crash-but-not-power-loss-durable; batch and os are accepted as aliases of off). Any other value (including true/on/1) is a FATAL startup error — use the exact vocabulary above. For a per-write RPO=0 knob use the X-Relata-Durability: sync request header instead of a deployment-wide switch (see guarantees → durability levels). |
RELATA_WAL_STRICT | — | Set true to escalate mid-stream WAL corruption to a hard startup error instead of dropping the corrupted suffix. When unset, recovery drops the unparseable tail and increments relata_wal_records_dropped_total. |
RELATA_PERSIST | — | Legacy persistence flag (still read; prefer RELATA_LOCAL_DATA_DIR). ⚠ still read at crates/relata-cli/src/serve.rs:16107 — removal tracked separately. |
RELATA_COMPACTION_TARGET_SEGMENTS | — | Target segment count before WAL compaction triggers. |
RELATA_COMPACTION_MIN_AGE_SECS | — | Minimum segment age before compaction considers it. |
RELATA_COMPACTION_GC_GRACE_SECS | — | GC grace period after compaction before old segments are deleted. |
RELATA_COMPACT_STRATEGY | size-tiered | Compaction segment-selection strategy. size-tiered uses all segments for the target type (default). leveled compacts the first level of up to 10 segments. time-window compacts only segments sharing the earliest partition_date bucket. |
RELATA_COMPACT_MAX_PARALLEL | 4 | Maximum compaction parallelism: bounds both how many object-store GET+decode pipelines run concurrently within one type's compaction, and how many types the auto-compaction scheduler / /admin/compact compact concurrently. Higher values reduce wall-clock time at the cost of additional network/CPU concurrency. |
RELATA_BENCH_NO_SAVE | — | Set 1 in relata-bench to skip auto-saving JSON results to docs/benchmarks/results/<git-sha>/. Best-effort: a missing git binary or unwritable path just prints a warning. |
RELATA_BENCH_STRICT | — | Set any non-empty value in relata-bench to enable server-class (strict) gate thresholds: B-INGEST ≥350K rows/s, B-SCAN p99 ≤10ms, B-FILTER p50 ≤7ms, G-VECTOR-INGEST ≥3000 vecs/s. Without this, loose thresholds accommodate thermal throttle on developer hardware. |
RELATA_OBJECT_STORE | — | Object-store URL selecting a native cloud backend ahead of the S3-compatible path: gcs://bucket/prefix or azure://container/prefix (crates/relata-storage/src/remote.rs). When unset, Relata uses the AWS_ENDPOINT_URL S3-compatible path. |
RELATA_SPILL_FORMAT | sstable | On-disk format for cold spill segments (crates/relata-storage/src/sstable.rs). sstable (default) writes LSM-style sorted blocks with a binary-searchable sparse index; json keeps the legacy newline-delimited text format. |
RELATA_WAL_FORMAT | binary | WAL payload encoding (crates/relata-storage/src/wal.rs). binary = compact 0xB1-magic layout (default); json = legacy/interop human-readable. Any non-json value selects binary. |
RELATA_WAL_IO | tokio | WAL writer I/O backend (crates/relata-storage/src/async_io.rs). tokio (default) | direct (O_DIRECT, unbuffered). Any other value — including io_uring, which is recognised syntax but has no working backend yet — exits the process at startup with a FATAL message; it is never silently accepted then failed at use time. |
RELATA_WAL_ARCHIVE_DIR | — | Directory where rotated WAL segments are archived for point-in-time recovery / disaster recovery (crates/relata-storage/src/backup.rs). When unset, WAL archiving returns NotConfigured and rotated segments are recycled. |
RELATA_HYDRATE_MAX_PARALLEL | 8 | Maximum number of concurrent remote-segment fetches during lazy hydration on restart (crates/relata-storage/src/store/remote_io.rs). Clamped to ≥ 1. Raise to warm the cache faster on high-bandwidth object-store links. |
RELATA_REMOTE_INDEX_SNAPSHOTS | false | When true, an indexer-role worker publishes each just-built secondary/range index shard to the shared object store, so a stateless query node with no local disk segment dir picks it up via the existing remote page-in path instead of scan-fallback. Each published shard is stamped with the schema generation it was built against; a query node rejects (falls back to scan) a downloaded shard whose generation doesn't match its own current one. Off by default — a newly landed primitive with no field mileage yet under real cross-node publish/consume churn. |
RELATA_EMPTY_WAL_ORPHANED_SNAPSHOTS_ALLOWED | false | Boot-time sanity check: if WAL replay recovers zero rows while the data directory still has old index-shard spill files present, that combination is strong evidence of masked data loss rather than a genuinely empty store, so relata serve refuses to start with a clear message. Set true only for the rare deliberate case of a fresh start against a reused data directory. |
RELATA_TABLE_GC_SHARDS | 1 | Number of independent storage shards (and matching index-lock partitions) per registered type. 1 (default) is byte-identical to the original single-shard design. N > 1 (capped at 256) spreads concurrent same-type writers across N independent write locks, materially raising same-type write throughput on multi-core hosts. A row's shard assignment is pinned for its whole life. See RELATA_TABLE_GC_SHARDS_AUTO for a cores-derived alternative to picking N by hand. |
RELATA_TABLE_GC_SHARDS_AUTO | false | When true and RELATA_TABLE_GC_SHARDS is unset, every newly-registered type gets a cores-derived shard count instead of the historical fixed 1. An explicit RELATA_TABLE_GC_SHARDS=N always wins. Opt-in because N > 1 changes full-table scan row order from strict insertion order to per-shard order. |
RELATA_TABLE_SCAN_PARALLEL | true | When true, cross-shard full-table scans and count/stat reads run across every storage shard concurrently instead of sequentially. Output is byte-identical either way — purely a lock-acquisition/materialization concurrency change. A complete no-op at the default single-shard configuration; only matters once RELATA_TABLE_GC_SHARDS/_AUTO is also raised. false opts back out. |
RELATA_START_EMPTY_ON_RESTORE_ALLOWED | false | Opt-in to restore the old behavior when durable-state restore fails at startup: warn and boot an empty store. Dangerous — that empty store's next flush overwrites the unreadable manifest, destroying the data. Default: a failed restore FATALs at startup instead, since durable data exists but could not be loaded. A brand-new deployment (genuinely absent manifest) is unaffected either way. |
RELATA_WAL_ROTATE_GRACE_SECS | 120 | How long a rotated-out, sealed WAL segment must sit on disk (measured from its last-write time) before the background pruner deletes it. The periodic remote-flush task rotates the live WAL right after each successful checkpoint. WAL replay at boot always discovers and replays any leftover sealed segments first, so a crash before this grace period elapses never loses data. |
RELATA_TIER_WARM_AGE_SECS | 2592000 (30 days) | Age threshold, from a segment's partition date, past which the background tier-transition scheduler moves a hot-tier sealed segment to warm storage within the same configured object store. A segment with no partition date is treated as maximally old (always eligible). |
RELATA_TIER_COLD_AGE_SECS | 7776000 (90 days) | Age threshold past which the same scheduler moves a warm-tier sealed segment to cold storage — the warm→cold mirror of RELATA_TIER_WARM_AGE_SECS. Defaults to 3x the warm threshold so a segment can't become cold-eligible on the same tick it became warm-eligible. |
RELATA_TIER_ORPHAN_RECLAIM_GRACE_SECS | 3600 (1h) | Grace period a tier-move's pre-move segment bytes are kept before the background orphan-reclaim scheduler physically deletes them — gives a cluster peer that hasn't yet observed the move time before the old bytes disappear. |
RELATA_FLUSH_MAX_PARALLEL | 4 | Maximum seal-flush parallelism: bounds how many (branch, type) tails are encoded and uploaded concurrently within one flush call, so one slow upload no longer stalls every other type's seal behind it. Clamped to ≥ 1. |
RELATA_MANIFEST_V2_WRITE | true | Each flush writes a sharded v2 manifest catalog alongside the original manifest files. Set false to opt back out — e.g. while validating an object-store backend without conditional-PUT support. Additive and fall-back-safe: the original manifest remains authoritative regardless of this flag. |
RELATA_SEAL_MAX_BYTES | 67108864 (64 MiB) | Byte-size threshold above which an unflushed write tail becomes due for a policy-driven seal to durable storage, independent of RAM-pressure spill. 0 disables the size trigger. |
RELATA_SEAL_MAX_AGE_SECS | 300 | Age threshold (seconds since the oldest unflushed row) above which a write tail is seal-due regardless of size. 0 disables the age trigger. |
RELATA_SEAL_MAX_ROWS | 100000 | Row-count threshold above which a write tail is seal-due. 0 disables the row-count trigger. |
RELATA_MAX_AGENCY_INDEX_BUCKET_ENTRIES | 0 (unbounded) | Per-bucket cap on live-row entries in a single tenant/type agency-index bucket. When set above 0, any bucket exceeding this size is evicted outright at the next prune cycle — a backstop for an always-growing tenant whose bucket would otherwise never shrink even as its row payloads spill to disk. |
Memory and cache
Adaptive defaults. When the budget vars below are unset, Relata derives them from detected hardware at startup — one shared ~75%-of-RAM pool split store ≈34% / index ≈11% / cache ≈11% / vectors ≈19%, plus
RELATA_EMBED_CONCURRENCY= cores andRELATA_SPECULATE_MAX_CONCURRENT= cores/4.freeclamps the pool to the 10 GB ceiling. Explicit env vars always win; if the RAM probe fails the legacy flat constants apply. Seecapacity-planningandcrates/relata-cli/src/resource.rs.
| Variable | Default | Description |
|---|---|---|
RELATA_STORE_MAX_RAM_MB | — (adaptive) | Global RAM budget cap across all stores. When unset, derived from detected RAM (store ≈34% of the ~75% pool); on server/cluster the legacy fallback is 1024 MB. Crossing the cap no longer spills synchronously on the inserting thread: an insert only flips an in-memory pressure flag, and a supervised background task (serve::maintenance::background_spiller_task, polling every 200 ms) performs the actual disk write + fdatasync off the hot path. |
RELATA_SESSION_DRAFT_TTL_HOURS | 24 | How long a session write-buffer (draft) is retained before automatic eviction. Set lower in memory-constrained environments. See X-Session-Draft header. |
RELATA_VECTOR_RAM_BUDGET_MB | 64 | Vector index (DiskANN) RAM budget. |
RELATA_GRAPH_RAM_BUDGET_MB | 64 | Graph (CSR) in-memory budget. When set, GRAPH_* ops build their adjacency into a disk-paged CSR, streaming edges block-by-block so peak build RAM is O(page budget), not O(edges). |
RELATA_GRAPH_RESIDENT_EDGE_WARN | 10000000 | Edge-count at which a resident (whole-RAM) graph build logs a warn! that it may OOM without paging — a nudge to set RELATA_GRAPH_RAM_BUDGET_MB. 0 disables the warning. |
RELATA_GRAPH_DELTA_LOG_CAP | 50000 | Max entries retained in LinkStore's bounded edge-delta log (crates/relata-graph/src/link_store.rs). Once exceeded, the oldest entries are dropped, so a cached CSR older than the oldest retained generation can no longer be reconciled via edge_deltas_since and falls back to a full rebuild. |
RELATA_GRAPH_CSR_DELTA_REBUILD_RATIO | 0.25 | Delta-size ÷ graph-edge-count ratio above which LinkStore's CSR-cache reconciliation prefers a full rebuild over CsrGraph::apply_delta — mirrors the tombstone-ratio-triggers-compaction convention in relata_storage::vector::COMPACT_TOMBSTONE_RATIO. |
RELATA_GRAPH_CSR_COUNTING_SORT_MAX_SPARSITY | 8.0 | Max node_count ÷ edge_count ratio at which build_pair (CSR/CSC construction) still prefers an O(V + E) counting sort over a comparison sort; past this ratio (and above a 1024-node floor) the histogram's O(V) cost dwarfs the actual edge work, so a comparison sort is used instead. |
RELATA_IDENTITY_RAM_BUDGET_MB | 64 | Identity index RAM budget. |
RELATA_EXEC_RAM_BUDGET_MB | — | Query execution working-memory cap. |
RELATA_JOIN_STRATEGY | auto | Join algorithm selection: hash (always hash join), sort-merge (always sort-merge join O((n+m) log n)), or auto (hash for small datasets, sort-merge when both sides exceed 100 000 rows). |
RELATA_DISKANN_MAX_RESIDENT | — (adaptive) | Max DiskANN pages to keep resident. When unset, derived from detected RAM (vectors ≈19% of the ~75% pool, ≈3.5 KiB/vector). |
RELATA_BLOOM_COLUMNS | tenant_id,object_type | Comma-separated column names for which per-column Bloom filters are built at segment flush time. Set to none to disable. Columns missing from a segment fail open (the segment is never falsely pruned). Both the segment-key bloom and per-column blooms are consulted live on the scan path (equality predicates prune disk segments pre-decode — executor.rs bloom hint → scan_as_of_arc_with_bloom in scan.rs). |
RELATA_SKETCH_COLUMNS | tenant_id,object_type,status | Comma-separated column names for which HyperLogLog (NDV) and Count-Min Sketch (value frequency) are maintained in-memory and updated on every row insert. Used by the cost-based optimizer to replace hardcoded 0.20 selectivity constants with data-driven per-value estimates. Set to none to disable; cold-start or disabled columns fall back to the NDV-sample heuristic. Memory: ~96 KB per tracked column per type. |
RELATA_VECTOR_QUANT | full | Vector quantization tier for HNSW node embeddings. full = raw f32 (no compression); fp16 = IEEE 754 half-precision, 2× memory reduction, ~0.1% error; binary = 1-bit per dimension packed into u64 words, 32× memory reduction, used as a hamming pre-filter before exact distance re-ranking. |
RELATA_VECTOR_COLD_RESIDENT_MAX | 100000 | Soft cap on RAM-resident vectors in an IVF cold bucket's staging area before the batch spills to the object-store-backed PagedAnnIndex. Only pages when an object store is configured. |
RELATA_MAX_VECTOR_K | 1000 | Hard cap on a vector query's requested k. 0 disables the cap. |
RELATA_CACHE_IDLE_TTL_SECS | 3600 | Evict TieredCacheTracker entries idle longer than N seconds. |
RELATA_CACHE_DECAY_KEEP_FACTOR | 0.9 | Temperature decay factor applied per decay sweep — entries below temperature × factor lose heat. |
RELATA_CACHE_L2_TO_L1_THRESHOLD | 4.0 | Temperature threshold above which a segment is promoted from L2 ring-buffer to L1 hot set. |
RELATA_PINNED_NAMESPACES | — | Comma-separated list of namespaces (the branch/tenant identity segment CacheCoordinator::partition_key_for composes into its cache-partition keys) to pin: each reserves a dedicated NVMe cache slice at startup and is evict-immune under cache pressure — eviction always falls back to non-pinned namespaces first. A branch of a pinned namespace starts unpinned (exact-match membership, not prefix-match); each shard of a pinned namespace pins independently. Unknown/malformed tokens (containing the reserved :: separator) are skipped with a warn!, never fail startup. |
RELATA_PINNED_NVME_SLOTS_PER_NAMESPACE | 64 | NVMe cache slots reserved per namespace listed in RELATA_PINNED_NAMESPACES. Parsed strictly — a non-integer value fails startup. Surfaced per-namespace as the relata_pinning_utilization gauge (tracked_partitions / this value, clamped to [0.0, 1.0]). |
RELATA_TOMBSTONE_CACHE_MAX_ROWS | 1024 | Max entries in the per-type tombstone cache before an arbitrary cold entry is evicted. Lower values save RAM at the cost of re-parsing on-disk tombstone files more frequently. |
RELATA_DECODED_SEGMENT_CACHE_MAX | 64 | Max decoded disk-segment entries cached in RAM before the oldest-mtime entry is evicted. Lower values save RAM at the cost of re-decoding cold segments. |
RELATA_ROW_SLOT_MAX | 256 | Max fields in a type's slotted-row schema dictionary before further rows of that type fall back to the legacy map representation instead of a dense per-row slot array. Guards wide/sparse types (hundreds of optional fields, few set per row) from wasting RAM on a slot array sized to the widest field ever seen. |
RELATA_PARQUET_MAX_DECOMPRESSED_MB | 4096 | Hard cap on the decompressed size of a single Parquet segment in MiB. Segments that expand beyond this limit are rejected at load time to prevent decompression-bomb OOM. |
RELATA_ENRICH_MODE | eager | Identity enrichment mode. lazy enqueues enrichment for background processing via EnrichmentQueue (lower write latency, slight graph-visibility delay). eager enriches inline before the write acks (default, preserves graph consistency). Startup fails on any other value. |
RELATA_MIN_FREE_DISK_MB | 256 | Minimum free disk space in MiB before Relata sheds inbound writes to protect the WAL and spill segments. 0 disables the guard entirely. |
RELATA_HTTP_MAX_CONNS | 4096 | Maximum concurrent in-flight HTTP connections. On the non-TLS path, a tower::limit::ConcurrencyLimitLayer back-pressures requests over the limit at the router. On the TLS path, a tokio::sync::Semaphore gates connections at accept time before they reach the router. This is the single knob for both paths — do not confuse with per-route rate limiting (RELATA_RATE_LIMIT_RPS). |
RELATA_REDIS_CACHE_MB | 64 | Redis-protocol-door value cache budget in MiB. 0 disables — every GET falls back to governed_get (the zero-regression path). The governed KvEntry row remains the single source of truth. |
RELATA_RESULT_CACHE_ENABLED | true | Enable the 16-shard query result cache. Set to false to disable globally (all queries hit the executor). |
RELATA_RESULT_CACHE_ENTRIES | 4096 | Historical entry-count knob, kept for API/config compatibility. Each shard is now a foyer S3-FIFO cache admitted purely by byte weight, so this no longer drives a separate structural cap — see RELATA_RESULT_CACHE_MAX_BYTES. |
RELATA_RESULT_CACHE_TTL_SECS | 300 | Default TTL for cached result sets in seconds. 0 means entries never expire (relying on type-tagged invalidation only). Per-query TTL override (WITH CACHE TTL <duration>) is not yet implemented. |
RELATA_RESULT_CACHE_MAX_BYTES | 134217728 | Starting total byte budget across all 16 shards (default 128 MiB). This is now the initial value only — the tick() feedback loop (wired into the 60 s background task) adjusts it ±5% toward RELATA_RESULT_CACHE_TARGET_HIT_RATIO at runtime, bounded by a RAM-derived ceiling. |
RELATA_RESULT_CACHE_MAX_ROWS | 10000 | Result sets with more rows than this are not cached (prevents pathological cache entries from exhausting the byte budget). |
RELATA_RESULT_CACHE_PROMOTE_ON_HIT | true | Historical LRU promote-on-hit knob, kept for compatibility. The S3-FIFO backend (foyer) always records access frequency on every get() — that's inherent to frequency-based admission — so the old peek-vs-promote distinction from the lru-crate backend no longer applies. |
RELATA_RESULT_CACHE_TARGET_HIT_RATIO | 0.85 | Target hit ratio the result-cache tick() adaptive-sizing loop steers the byte budget toward. Below target → budget grows 5%/tick; at or above target → budget shrinks 5%/tick (reclaiming RAM for other consumers), bounded to [16 MiB, detected_ram × 11%]. Clamped to [0.0, 1.0]. |
RELATA_BENCH_CACHE_HIT_GATE_US | 50 | Hit-latency gate (µs, p99) for the relata-bench result-cache suite. Raise on slower shared/cloud hardware where the fixed 50µs ceiling breaches on scheduler jitter rather than real contention. |
RELATA_VECTOR_RESULT_CACHE_ENABLED | true | Enable the vector KNN query-result cache (KnnResultCache, crates/relata-storage/src/vector_cache.rs) — memoises (query_vector, k, filter_hash, tenant_id, model_tag) -> top-k ids/scores below the full-SQL result cache, so a repeated embedding skips the hot TurboVec scan and any cold-tier IVF paging. Set to false to disable globally. |
RELATA_VECTOR_RESULT_CACHE_MB | 64 | Byte budget for the vector KNN result cache. LRU-evicted when exceeded. |
RELATA_VECTOR_RESULT_CACHE_TTL_SECS | 60 | TTL for cached KNN results in seconds. Independent of the write-triggered bucket invalidation (any embedding write into a (object_type, modality, model_tag, tenant_id) bucket evicts every cached result for that bucket regardless of TTL). |
Usage example:
RELATA_VECTOR_RESULT_CACHE_MB=128 RELATA_VECTOR_RESULT_CACHE_TTL_SECS=120 cargo run -p relata-cli -- serveraises the KNN result-cache budget to 128 MiB and its TTL to 120s;RELATA_VECTOR_RESULT_CACHE_ENABLED=false cargo run -p relata-cli -- servedisables the cache entirely (every KNN/HYBRID_SEARCHvector sub-query re-runs the hot scan + cold-tier paging in full).
| RELATA_CACHE_DISK_PATH | — | Directory path for the optional disk-tier segment cache (foyer HybridCache). When unset, the cache is RAM-only (RowGroupCache). Set together with RELATA_CACHE_DISK_GB to enable the disk tier. |
| RELATA_CACHE_DISK_GB | — | Maximum disk space (GiB) reserved for the disk-tier segment cache. Ignored when RELATA_CACHE_DISK_PATH is unset. Integer; 0 or unset disables the disk tier. |
| RELATA_QUERY_ARENA | true | When true (default), the in-memory sort path arena-allocates its keyed buffer via bumpalo — one bump allocation for the whole intermediate result set instead of repeated malloc/free per row. Set to false to fall back to standard heap allocation (useful for memory-profiling or if a bumpalo bug is suspected). |
Query pattern tracker
| Variable | Default | Description |
|---|---|---|
RELATA_PATTERN_HISTORY_LEN | 16 | Number of recent query template hashes kept per session for Markov chain transitions. Higher values improve prediction accuracy at the cost of per-session memory. |
RELATA_PATTERN_SESSION_TTL_SECS | 300 | Seconds of inactivity before a session is GC'd from the pattern tracker. |
RELATA_PREDICT_MIN_CONFIDENCE | 0.3 | Minimum Markov transition confidence (fraction of observations) for a prediction to be returned. Range: 0.0–1.0. |
RELATA_PREDICT_TOP_K | 2 | Maximum number of predicted next queries returned per prediction request. |
RELATA_PREDICT_INFER_PARAMS | false | Propagate changed literals from the triggering query into predictions (search('y') after a historical search('x') → details('x') predicts details('y')). Off = predictions replay each template's last session binding verbatim. |
Speculative prefetch
| Variable | Default | Description |
|---|---|---|
RELATA_SPECULATE_ENABLED | true | Kill switch for the speculative prefetch pipeline. false disables prediction submission and the drain worker entirely. |
RELATA_SPECULATE_MAX_CONCURRENT | 1 (adaptive) | Maximum speculative queries executing concurrently. When unset, derived from detected cores (cores/4, min 1). Waiting work back-pressures into the bounded submit queue (overflow drops are counted in relata_speculative_dropped_total). |
RELATA_SPECULATE_HOURLY_CAP | 1000 | Fixed-window cap on speculative executions per hour. Over-cap work is dropped and counted. 0 denies all speculation (equivalent to disabling). |
Callers can scope the pattern model per workflow by sending an X-Relata-Session header; without it, one model is shared per principal+org.
Graph index and algorithms
| Variable | Default | Description |
|---|---|---|
RELATA_GRAPH_CACHE_BYTES | 268435456 (256 MiB) | Total byte budget for the 16-shard PagedGraphCache (CSR adjacency cache, crates/relata-query/src/graph_cache.rs). Higher values keep more (object_type × tenant) adjacency graphs RAM-resident. |
RELATA_PAGED_GRAPH_CACHE_CAP | 32 | Max number of (object_type × tenant × orientation) CSR graphs held in RAM by the investigation-ops cache (crates/relata-query/src/investigation_ops.rs). Oldest is evicted on overflow. |
RELATA_GRAPH_PREWARM | true | Whether to speculatively build + cache the CSR graph after bulk ingest (crates/relata-cli/src/serve/ingest.rs). Any value other than false/0/no is treated as enabled. |
RELATA_GRAPH_PREWARM_THRESHOLD | 1000 | Minimum batch size (rows ingested) that triggers the background graph prewarm. Batches smaller than this skip the prewarm. |
RELATA_BETWEENNESS_APPROX_THRESHOLD | 10000 | Node count above which betweenness_centrality_approx switches from exact Brandes to sampling-based (crates/relata-graph/src/gds.rs). Raise for more exactness on larger graphs at CPU cost. |
RELATA_SPECULATE_GRAPH | false | Opts in to speculative prefetch / caching for GRAPH_* queries (crates/relata-query/src/query_pattern.rs). Off by default because graph results depend on mutable CSR state — enable only when graph mutation is low-frequency. |
Vector index tuning
| Variable | Default | Description |
|---|---|---|
RELATA_HNSW_AUTO_TUNE | true | Kill-switch for automatic HNSW ef_search recall tuning (crates/relata-storage/src/vector.rs). Disabled only by "false"/"0". |
RELATA_HNSW_ADAPTIVE_DEFAULTS | true | Whether new cold-path DiskAnnIndex buckets pick M/M0/ef_construction adaptively from the current corpus-size hint (crates/relata-storage/src/vector.rs::recommended_hnsw_params) instead of always building at the fixed large-corpus default. Set to false to pin every new index to the fixed DEFAULT_M/DEFAULT_EF_CONSTRUCTION tier. Strictly parsed via relata_core::bool_env: any set-but-unrecognised value is a fatal startup error. Never consulted by an explicit HnswIndex::with_params call. |
RELATA_AUTOTUNE_INTERVAL | 10000 | How often (every N searches) the HNSW ef_search auto-tuner re-evaluates recall. Higher values sample less frequently (lower overhead). |
RELATA_IVF_THRESHOLD | 1000000 | Vector count at which the cold tier switches from HNSW to IVF-PQ (crates/relata-storage/src/ivf_builder.rs). Below this, the hot HNSW tier serves all queries. |
RELATA_IVF_N_LISTS | 0 | Number of coarse centroids (lists) when building the IVF-PQ cold tier. 0 = auto sqrt(N). |
RELATA_IVF_N_PROBE | 8 | Number of IVF centroids scanned per query (recall/latency tradeoff). Higher = better recall, more CPU. |
RELATA_VECTOR_COLD_TIER | ivf-pq | Cold-tier ANN algorithm to switch to above the IVF threshold. ivf-pq (default) or hnsw to keep the hot-tier algorithm in the cold tier. |
Query parse cache and optimizer
| Variable | Default | Description |
|---|---|---|
RELATA_PARSE_CACHE_MAX_ENTRIES | 4096 | Max entries in the process-global parsed-SQL cache (crates/relata-query/src/parser.rs). LRU eviction above the cap. |
RELATA_PARSE_CACHE_MAX_BYTES | 67108864 (64 MiB) | Total byte budget for the parsed-SQL cache. |
RELATA_JOIN_REORDER | true | Enables the cost-based (DPhyp-style) join-reorder optimizer (crates/relata-query/src/cost.rs). When false/0, the input join order is preserved unchanged. |
RELATA_CACHE_PER_TENANT_MAX_MB | cache_bytes ÷ 4 | Per-tenant byte cap on the query-result cache (crates/relata-query/src/result_cache.rs). Prevents a noisy tenant from evicting everyone else's results. |
gRPC server
| Variable | Default | Description |
|---|---|---|
RELATA_GRPC_TIMEOUT_MS | 30000 | Per-RPC deadline in milliseconds — prevents a slow client from holding a worker forever. 0 disables the timeout (air-gap / batch workloads). |
RELATA_GRPC_TIMEOUT_SECS | 30 | Wall-clock deadline in seconds for gRPC streaming scan operations (spawn_blocking paths that cannot be interrupted by an async timeout). Applied per-stream as an Instant deadline checked at each batch boundary. |
Benchmark harness
| Variable | Default | Description |
|---|---|---|
RELATA_BIN | — | Path to a prebuilt relata binary for the relata-bench HTTP-door suite (bench_http_door). When unset, the suite looks for the release binary next to the bench binary (cargo build -p relata-cli --release first). |
RELATA_GRAPH_AUTO_PAGE_RAM_BUDGET_MB | 512 | RAM budget (MB) auto-selected when a graph build's pre-materialization edge-count estimate crosses the resident-edge warning threshold and no explicit graph RAM budget is already configured — routes the build to the disk-paged leg automatically instead of building fully resident and only warning about it afterward. Ignored once an explicit budget is set. |
RELATA_QUERY_PARALLEL_FILTER_THRESHOLD | 50000 | Row-count threshold at/above which a plain SELECT ... WHERE filter pass partitions rows and evaluates them on the parallel worker pool instead of one single-threaded batch. Below the threshold, parallel-dispatch overhead outweighs the win. 0 disables parallelism (always serial). |
RELATA_QUERY_PARALLEL_SCAN_FILTER_THRESHOLD | 50000 | Same threshold/overhead tradeoff as RELATA_QUERY_PARALLEL_FILTER_THRESHOLD, applied to the post-scan tombstone + tenant-visibility filter every scan dispatch converges through. |
RELATA_QUERY_PARALLEL_JOIN_THRESHOLD | 50000 | Row/element-count threshold at/above which hash-join and sort-merge-join build/probe/sort phases dispatch to the parallel worker pool instead of running serially. Same size/overhead tradeoff and 0-disables contract as the filter thresholds above. |
RELATA_STORAGE_PARALLEL_SCAN_THRESHOLD | 50000 | Candidate-row-count threshold at/above which the storage layer's own row-filtering scan pass partitions candidates across the parallel worker pool. Same tradeoff and 0-disables contract as the query-layer thresholds above; scan order is preserved. |
RELATA_BG_RAYON_THREADS | — (adaptive, cores/2, min 1) | Worker-thread count for the dedicated background compute pool that vector-index bulk builds (HNSW/IVF/Paged-ANN) run under, isolated from the main worker pool so a large background index build can't starve query execution's own parallel work. |
RELATA_BLOOM_FETCH_CACHE_ENABLED | true | Enables the process-wide bloom-filter fetch cache that restores segment-bloom prune precision without holding every segment's bloom bytes permanently resident. false disables it — hydration then always fails open (fetches every zone-map-admitted candidate segment) for entries whose bloom bytes aren't cached. |
RELATA_BLOOM_FETCH_CACHE_MB | 32 | Byte budget for the bloom-fetch cache above. LRU-evicted when exceeded; a segment falling out of budget simply reverts to fail-open pruning for that segment — never a correctness change. |
RELATA_DECODED_SEGMENT_CACHE_MAX_BYTES | 536870912 (512 MiB) | Byte budget for the decoded disk-segment cache, keyed on each segment's actual size rather than a bare entry count (so a handful of large segments and a thousand tiny ones don't count identically against the cap). When a row-store RAM budget (RELATA_STORE_MAX_RAM_MB) is configured, this value is clamped down to it by default — set it explicitly to opt back into an independent budget. |
RELATA_LAZY_TYPES | — | Comma-separated list of object-type names (e.g. LogEvent,MetricSample) enriched lazily in the background regardless of the global RELATA_ENRICH_MODE. Types not listed fall back to the global setting; this list only ever adds lazy behavior, never forces a type back to eager. |
RELATA_HTTP_MAX_INFLIGHT_REQUESTS | 4096 | Maximum concurrent in-flight HTTP requests admitted at the router, independently tunable from RELATA_HTTP_MAX_CONNS (which bounds TLS connection count, not request concurrency). Requests over the limit back-pressure at the router. |
RELATA_GRAPH_EXACT_ALGO_MAX_NODES | 20000 | Node-count ceiling for the exact-memory/exact-time graph operators (GRAPH_DIAMETER, GRAPH_APSP) on the resident leg. A graph past this cap is rejected up front instead of silently materializing a full distance matrix — an OOM/CPU-exhaustion guard, especially relevant on the free profile. 0 disables the cap. |
RELATA_GRAPH_UNPAGED_COMMUNITY_MAX_EDGES | same as the resident-edge warning threshold (10000000) | Edge-count cap for the GRAPH_COMMUNITY algorithm variants with no disk-paged leg (Leiden, and multi-level Louvain). Single-level Louvain already routes through the paged leg and is unaffected. A pre-scan estimate past this cap is rejected up front rather than building the whole graph resident. 0 disables the cap. |
RELATA_GRAPH_MAX_K_SHORTEST | 50 | Hard cap on GRAPH_K_SHORTEST's requested K. The algorithm's cost scales with K, so an unbounded value would let a caller pin a worker thread indefinitely; a request above the cap is rejected at parse time. |
RELATA_VF3_ENABLED | true | Kill-switch for the VF3 subgraph-isomorphism matcher that executes multi-hop Cypher MATCH patterns. When false, every pattern query routes to the slower per-hop traversal fallback regardless of any per-query matcher hint. |
Wire protocol ports
HTTP is always on. pgwire requires RELATA_BEARER_TOKEN. Every other door
auto-enables when RELATA_BEARER_TOKEN is set (any profile) — set
<DOOR>_ENABLE=false to force it off, or <DOOR>_ENABLE=true to force it on
without a token (only on free; non-free is fail-closed without a token).
All protocol doors bind to loopback (127.0.0.1) by default; HTTP/gRPC on
the server/cluster profiles bind 0.0.0.0. Every bind var is a plain
override on every profile, not license-gated.
| Protocol | Enable flag | Port var | Default port | Bind var | Default bind |
|---|---|---|---|---|---|
| HTTP API | always on | RELATA_PORT | 9090 | RELATA_HTTP_BIND | profile: 127.0.0.1 (free) / 0.0.0.0 (server/cluster) |
| gRPC | always on | RELATA_GRPC_PORT | 50051 | RELATA_GRPC_BIND | profile: 127.0.0.1 (free) / 0.0.0.0 (server/cluster) |
| PostgreSQL wire | token required | RELATA_PG_PORT | 5433 | RELATA_PG_BIND | 127.0.0.1 |
| S3-compatible | token-gated (RELATA_S3_ENABLE) | RELATA_S3_PORT | 9191 | RELATA_S3_BIND | 127.0.0.1 |
| Redis | token-gated (RELATA_REDIS_ENABLE) | RELATA_REDIS_PORT | 6379 | RELATA_REDIS_BIND | 127.0.0.1 |
| MongoDB | token-gated (RELATA_MONGO_ENABLE) | RELATA_MONGO_PORT | 27017 | RELATA_MONGO_BIND | 127.0.0.1 |
| Neo4j HTTP | token-gated (RELATA_NEO4J_ENABLE) | RELATA_NEO4J_PORT | 7474 | RELATA_NEO4J_BIND | 127.0.0.1 |
| Bolt | token-gated (RELATA_BOLT_ENABLE) | RELATA_BOLT_PORT | 7687 | RELATA_BOLT_BIND | 127.0.0.1 |
| ClickHouse HTTP | token-gated (RELATA_CLICKHOUSE_ENABLE) | RELATA_CLICKHOUSE_PORT | 8123 | RELATA_CLICKHOUSE_BIND | 127.0.0.1 |
| ClickHouse native TCP | token-gated (RELATA_CLICKHOUSE_NATIVE_ENABLE) | RELATA_CH_NATIVE_PORT | 9000 | RELATA_CH_NATIVE_BIND | 127.0.0.1 |
| Arrow Flight | token-gated (RELATA_FLIGHT_ENABLE) | RELATA_FLIGHT_PORT | 8815 | RELATA_FLIGHT_BIND | 127.0.0.1 |
Additional door options:
| Variable | Description |
|---|---|
RELATA_S3_SECRET_KEY | SigV4 secret for the S3 door. Defaults to RELATA_BEARER_TOKEN. When set (the default when a token is present), the door REQUIRES verified SigV4 and rejects plaintext bearer / unsigned access-key auth. |
RELATA_S3_ALLOW_PLAINTEXT | Default false. Dev/legacy opt-out: set true to accept plaintext bearer / unsigned access-key auth on the S3 door even when a secret is configured (the credential travels in cleartext and is forgeable — do not use in production). |
RELATA_MONGO_DEBUG | Set true for verbose MongoDB wire debug logging. |
RELATA_BOLT_DEBUG | Set true for verbose Bolt wire debug logging. |
RELATA_DOOR_READ_TIMEOUT_SECS | Default 1800 (30 min). Idle-read timeout on the PostgreSQL wire door. Connections that receive no data for this many seconds are closed. Increase for long-running ETL sessions; decrease to reclaim idle connections faster. |
RELATA_REDIS_READ_TIMEOUT_SECS | Default 30. Idle-read timeout on the Redis RESP door. Connections idle for this many seconds are closed. |
RELATA_PGWIRE_STMT_TIMEOUT_MS | Default 30000 (30 s). Per-statement timeout on the pgwire door. A query running longer than this is cancelled and the client receives an error. |
RELATA_MONGO_MAX_CONNS | Default 100. Max concurrent connections on the MongoDB wire door. |
RELATA_S3_BODY_LIMIT_MB | Default 4 (4 MiB). Max inline S3 PutObject body size. Larger objects must use multipart upload. |
RELATA_S3_MULTIPART_LIMIT_MB | Default 10240 (10 GiB). Max total size for S3 multipart uploads. Individual parts default to 5 MiB. |
RELATA_S3_BLOB_THRESHOLD_MB | Default 4 (4 MiB). Objects larger than this are stored as content-addressed blobs in the object store; smaller objects are inlined. |
RELATA_S3_BODY_TEXT_CAP | 65536 |
RELATA_S3_NOTIFY_URL | — |
RELATA_FLIGHT_CONCURRENCY_PER_CONN | 256 |
RELATA_FLIGHT_MAX_CONCURRENT_STREAMS | 256 |
RELATA_FLIGHT_TIMEOUT_MS | 30000 |
RELATA_FLIGHT_TICKET_ROW_CAP | 10000000 |
RELATA_FLIGHT_STREAM_BYTE_CAP | 10737418240 (10 GiB) |
RELATA_FLIGHT_FANOUT_STREAM | true |
TLS / mTLS
| Variable | Default | Description |
|---|---|---|
RELATA_TLS_CERT | — | Path to the TLS certificate (PEM) for in-process HTTP TLS termination. When set with RELATA_TLS_KEY, the HTTP listener binds with rustls TLS. Required on every profile — including free — unless RELATA_PLAINTEXT_OK resolves true (see that row for the loopback default). |
RELATA_TLS_KEY | — | Path to the TLS private key matching RELATA_TLS_CERT. |
RELATA_GRPC_TLS_CERT | — | gRPC TLS certificate path. |
RELATA_GRPC_TLS_KEY | — | gRPC TLS key path. |
RELATA_GRPC_TLS_CA | — | CA certificate for gRPC mTLS (mutual TLS client verification). relata cluster-init prints this path so the supervisor can forward it to peers. |
RELATA_GRPC_PLAINTEXT_OK | false | Allow gRPC listener to boot without TLS (true/1/yes/on). Production hazard. Without it, missing TLS config is a hard startup error. On server/cluster this alone is not enough — see RELATA_SECURITY_MODE above, which must also be open. |
RELATA_HTTP_TIMEOUT_SECS | 30 | Per-request HTTP timeout for the axum server's graceful-shutdown drain window and long-poll handlers. Distinct from the SDK-side timeout= constructor arg. |
RELATA_GRPC_MAX_DECODE_BYTES | 16777216 | Max inbound gRPC message size (bytes) before rejection. Raise for large-batch ingest. |
RELATA_GRPC_CONCURRENCY_PER_CONN | 256 | Max concurrent in-flight requests per gRPC connection. |
RELATA_GRPC_MAX_CONCURRENT_STREAMS | 256 | Max concurrent HTTP/2 streams per gRPC connection. |
RELATA_JWKS_GRACE_SECS | 600 | JWKS cache grace window (seconds) — a stale key is served this long past expiry while a refresh is attempted (oidc-verify mode). |
RELATA_PGWIRE_ORG | — | Organization/agency attribute stamped on the principal for the Postgres-wire door (psql has no native org concept). Unset = no org attribute. |
RELATA_PG_TLS_CERT | — | Path to the PEM certificate file for pgwire (Postgres-wire) TLS. When both RELATA_PG_TLS_CERT and RELATA_PG_TLS_KEY are set, the pgwire listener binds with TLS; when either is absent TLS is disabled and the listener operates in plaintext mode. |
RELATA_PG_TLS_KEY | — | Path to the PEM private-key file for pgwire TLS. Required alongside RELATA_PG_TLS_CERT; ignored when the cert is unset. |
RELATA_PG_COPY_MAX_BYTES | 1073741824 | Maximum in-memory buffer size for a COPY <type> FROM STDIN pgwire session (bytes). Payloads exceeding this limit are rejected with an error to prevent a single client from exhausting server memory. Default: 1 GiB. |
RELATA_SCATTER_MAX_PARALLEL | 64 | Max parallel fan-out requests per cluster scatter-gather read (clamped ≥ 1). |
RELATA_SCATTER_PEER_TIMEOUT_MS | 10000 | Per-peer request timeout (ms) for cluster scatter-gather fan-out. Clamped ≥ 1 ms. Raise on high-latency inter-node links; lower to fail fast on unreachable peers. |
RELATA_SLOW_QUERY_MS | 500 | Query wall-clock threshold (ms) above which a query is recorded in the slow_queries ring surfaced on the metrics dashboard. |
RELATA_WAL_PUT_MAX_ATTEMPTS | 3 | Max object-store PUT attempts per WAL segment upload (clamped ≥ 1). |
RELATA_PARQUET_COMPRESSION | zstd | Parquet segment compression codec. Accepted: zstd (default, level 3), zstd:<level> (level 1-22), lz4, snappy, none. ZSTD level 3 gives 2-4× size reduction vs Snappy at similar decode throughput. |
RELATA_FLUSH_SEGMENT_MAX_ROWS | 0 | Cap on rows per Parquet segment during flush to the object store. 0 = unbounded (legacy single-segment). Non-zero splits large flushes into multiple smaller segments for better S3 multipart upload behaviour and reduced p99 on very large commits. |
RELATA_LAZY_RESTART | false | When true, startup loads the manifest catalog only (O(manifest), not O(rows)) instead of eager row restoration. Faster cold starts; older segments hydrate on demand. |
RELATA_HYDRATE_RECENT_SEGMENTS | 0 | With lazy restart on, hydrate only the newest N segments into RAM at startup. 0 = fully lazy (all segments hydrate on demand). Set to a small number (e.g. 3) to keep recent data hot. |
RELATA_MAX_AGENCY_INDEX_BUCKETS | 200000 | Soft cap on total (type, agency) agency-index buckets before the memory-pressure spill path evicts the smallest-live-set buckets first. Bounds O(tenants × types) index growth; evicted buckets rebuild lazily and reads stay correct via the field-filtered fallback. |
RELATA_EMBED_QUEUE_MAX | 100000 | Cap on the embedding-backlog queue (MediaWorker). Tasks dropped beyond cap; relata_embed_queue_dropped_total counter increments. |
RELATA_EMBED_QUEUE_HWM | 90% of RELATA_EMBED_QUEUE_MAX | High-water mark for the embed queue. When queue depth ≥ HWM, all ingest endpoints return 429 Too Many Requests with Retry-After so callers slow down before silent drops begin. Response body includes embed_queue_depth. Set equal to RELATA_EMBED_QUEUE_MAX to disable. |
RELATA_EMBED_TIMEOUT_MS | 30000 | Sidecar embedding HTTP call timeout in ms. On timeout, the drain worker logs + retries next cycle. |
RELATA_EMBED_CIRCUIT_COOLDOWN_MS | 60000 | Circuit-breaker cooldown for the embedder sidecar. After N consecutive failures, enqueue fast-fails until the cooldown elapses. |
RELATA_EMBED_BATCH_SIZE | 32 | Number of texts per sidecar embedding HTTP call. GPUs are designed for batched inference — batch_size=32 typically gives 5-10× throughput over batch_size=1. Range [1, 1024]. |
RELATA_EMBED_CONCURRENCY | 4 (adaptive) | Number of concurrent drain workers sharing the embedding queue. When unset, derived from detected cores (= cores). Multiple workers keep the GPU saturated while the CPU writes previous results back. Combined with RELATA_EMBED_BATCH_SIZE, gives ~15-50× throughput over the sequential per-row path. |
RELATA_SEARCH_PRESET | balanced | Search relevance preset: strict (exact-match preferred, no typo tolerance — governed/production), balanced (light typo tolerance, prefix on short tokens — general-purpose), or lenient (edit-distance 2, fuzzy on — demo/evaluation). See Search presets. |
RELATA_SEARCH_LAST_TERM_PREFIX | true | When true, the /search handler treats the last whitespace-delimited token as a prefix and unions BM25 results with prefix_search hits — enabling search-as-you-type without explicit wildcard syntax. Set to false to disable. Can also be overridden per-request via the lastTermIsPrefix body field. |
RELATA_SEARCH_LANG | en | ISO 639-1 language code for the built-in stemmer. 15 hand-rolled stemmers ship (en, fr, de, es/pt (shared stem_es), it, nl (Dutch), sv (Swedish), no (Norwegian), da (Danish), fi (Finnish), hu (Hungarian), ro (Romanian), ru (Russian Cyrillic), tr (Turkish), ar (Arabic)) — see crates/relata-storage/src/search.rs:3189-3745. Unknown codes fall back to English. CJK text (Han/Kana/Hangul) is always bigram-segmented regardless of this setting. Read once at startup — restart required for changes to take effect. |
RELATA_WAL_MIRROR_CHANNEL_CAP | 4096 | Cap on the object-store WAL mirror channel. Prevents unbounded memory if the remote WAL drain falls behind. |
RELATA_STOP_WORDS_LANG | en | Stop-word language: en for built-in English list, none to disable. |
RELATA_STOP_WORDS_FILE | — | Path to a custom stop-word file (one word per line). Overrides the built-in list when set. |
RELATA_SYNONYMS_FILE | — | Path to a JSON synonym file for query-time expansion, e.g. {"phone": ["telephone", "mobile"]}. |
RELATA_FACETS_<Type> | — | Comma-separated list of facetable attributes per type, e.g. RELATA_FACETS_Product=category,brand. |
RELATA_RANKING_<Type> | — | Per-type custom ranking rules, e.g. RELATA_RANKING_Article=recency:published_at:86400,popularity:weight:0.3. |
RELATA_MTLS_CA_CERT_PATH | — | CA certificate (PEM) used to verify client certs. Required for RELATA_AUTH_MODE=mtls. |
RELATA_MTLS_REQUIRE_CLIENT_CERT | — | Require client certificate on TLS handshake. |
RELATA_MTLS_ALLOWED_DNS_SANS | — | Comma-separated list of allowed DNS SANs in client certs. |
RELATA_TLS_HANDSHAKE_TIMEOUT_SECS | 10 | Seconds a TLS client gets to complete the handshake on the HTTP listener before the connection is dropped and its connection permit released. Guards against slow-handshake attacks exhausting the connection-accept semaphore. 0 falls back to the default. |
Rate limiting
| Variable | Default | Description |
|---|---|---|
RELATA_RATE_LIMIT_RPS | free: 10000, server/cluster: 100000 | Global per-IP request rate (requests/sec). Free defaults high (dev — false positive). Licensed tiers default 10x free (database-class throughput). Explicit env var overrides all profiles. |
RELATA_RATE_LIMIT_BURST | free: 10000, server/cluster: 100000 | Burst capacity above RELATA_RATE_LIMIT_RPS. Matches the RPS default per profile. |
RELATA_ACL_GRANT | — | Comma-separated ACL grants for custom types, e.g. CustomClaim:read+write,CustomDispute:read+write. Grants every door role (http-client, pgwire-client, grpc-client, s3-client, flight-client, clickhouse-client, mongo-client, redis-client, bolt-client, mcp-client, cluster-shard-client) ACL allow on the named types (read grants also reach the internal system principal so MV/workflow refresh keeps working), so ingest, query, and MCP tools all work without 403. Bare type name (no :perms) defaults to read. Accepted permissions: read, write, override. Read at startup — restart required. See Access Control & Permissions. |
RELATA_ACL_GRANT_<DOOR> | — | Per-door narrowing (or standalone grant) of RELATA_ACL_GRANT (#4708). Same TypeA:read+write,TypeB:read spec syntax, parsed independently per door — when it names a type the global spec also names, it replaces that door's permission set for the type rather than adding to it (e.g. global grants a type read+write; setting the pgwire variant to just write makes pgwire write-only while every other door keeps read+write). A type named only here is granted, standalone, to that one door — the global var doesn't need to be set at all. <DOOR> is the door role's name with the -client suffix dropped and upper-cased: HTTP, PGWIRE, GRPC, S3, FLIGHT, CLICKHOUSE, MONGO, REDIS, BOLT, MCP, CLUSTER_SHARD. Read at startup — restart required. |
RELATA_DISKANN_DISK_RESIDENT | — | When true, writes a .rgph sidecar alongside the HNSW graph for disk-resident ANN beam-search. Requires a backing object store. |
RELATA_DISKANN_PROFILE | balanced | One-var preset (fast|balanced|quality, #4954) over the four build-quality/query-rerank knobs below (ALPHA/MAX_DEGREE/L_BUILD/RERANK_FACTOR). balanced reproduces their pre-existing defaults exactly — a no-op if you never set it. fast trades recall for lower build cost/memory and faster queries (alpha 1.3, max_degree 24, l_build 64, rerank_factor 4); quality trades build cost and query latency for recall (alpha 1.15, max_degree 64, l_build 150, rerank_factor 10). An explicit individual var below still wins over the active profile. Has no effect unless RELATA_DISKANN_DISK_RESIDENT=true. |
RELATA_DISKANN_ALPHA | 1.2 (or RELATA_DISKANN_PROFILE's alpha) | Alpha selectivity for the Vamana RobustPrune step. Higher values (e.g. 1.4) prune more aggressively, reducing edge count at the cost of recall. Must be >= 1.0. |
RELATA_DISKANN_MAX_DEGREE | 32 (or RELATA_DISKANN_PROFILE's max_degree) | Maximum out-degree per node in the Vamana graph. Bounds memory used by the build-phase adjacency lists. |
RELATA_DISKANN_L_BUILD | 100 (or RELATA_DISKANN_PROFILE's l_build) | Candidate list size L during the Vamana greedy-search build pass. Larger values improve graph quality at the cost of build time. |
RELATA_COLD_TIER_FAIL | open | DiskANN cold-tier page-in failure mode (crates/relata-storage/src/paged_ann.rs). open (default): a failed cold-tier read returns an empty result (observability-only — the query succeeds with fewer candidates). closed: a failed cold-tier read fails the query. Set to closed only when you need hard failure semantics on cold-tier I/O errors. |
RELATA_COLD_ANN | rebuild | Cold-tier IVF absorb strategy (crates/relata-storage/src/paged_ann.rs / ivf_builder.rs). rebuild (default): the legacy ColdIvfBucket behaviour — a full k-means rebuild of the resident overflow once it doubles. incremental: routes inserts into a centroid-incremental tier (IncrementalCentroidIndex) that appends to the nearest centroid's posting list and periodically re-centres only the centroids that changed, never rerunning k-means over the whole corpus. |
RELATA_READ_RATE_LIMIT_RPS | — | Read-path rate limit (separate bucket from write path). |
RELATA_MEMORY_RATE_LIMIT_RPS | — | In-memory scan rate limit. |
RELATA_RATE_LIMIT_AUTH_FAIL_RPS | free: 10000, server/cluster: 10 | Brute-force throttle after auth failure. The server/cluster default is intentionally low (10 RPS) to slow credential stuffing; free uses the same value as RELATA_RATE_LIMIT_RPS. Always ≥1 (.max(1) guard). |
RELATA_MAX_CONNS | — | Max concurrent connections accepted. |
RELATA_WEBHOOK_MAX_INFLIGHT | 32 | Ceiling on concurrently in-flight alert-webhook deliveries (spawn_alert_webhooks). Deliveries beyond the cap are dropped with a warn!; deliveries under the cap get a bounded retry with exponential backoff on 5xx/timeout before giving up. Raise for high-volume alerting pipelines; lower to bound webhook concurrency. Zero/invalid falls back to 32. |
RELATA_QUERY_QUOTA | — | Per-principal read-cost cap (cost units, not rows). A principal whose cumulative read cost exceeds this within RELATA_QUERY_QUOTA_WINDOW_SECS receives a 429. Distinct from RELATA_MAX_RESULT_ROWS (which caps result size). |
RELATA_QUERY_TIMEOUT_SECS | — | Per-query execution deadline (seconds); a query past it aborts with a timeout error so it can't pin a worker. Unset/0 = no limit. |
RELATA_QUERY_MAX_INFLIGHT | adaptive (detected cores, min 1) | CPU-query admission control: max POST /query executions allowed to run concurrently inside the offloaded execution core. A request that can't get a slot within RELATA_QUERY_ADMISSION_WAIT_MS is shed with 503 + Retry-After instead of queueing unboundedly. /health//health/ready are exempt. |
RELATA_QUERY_ADMISSION_WAIT_MS | 50 | Max time (ms) POST /query waits for a CPU-query admission slot before shedding. |
RELATA_QUERY_CPU_THREADS | adaptive (detected cores × 4, min 4) | Max blocking-pool threads (tokio::runtime::Builder::max_blocking_threads) on the real server runtime — the pool an offloaded /query execution (block_in_place) runs on. Overrides tokio's flat built-in default (512). |
RELATA_MAX_WATCH_SUBSCRIPTIONS | 1024 | Max concurrent WATCH subscriptions; new ones past the cap are shed (each re-evaluates on every commit, so an unbounded count amplifies commit latency). |
RELATA_MAX_RESULT_ROWS | — | Hard ceiling on result set size. |
RELATA_TRUSTED_PROXIES | — | Comma-separated trusted proxy CIDRs for real-IP extraction. |
RELATA_TRUST_UPSTREAM_PROXY | — | Set true to trust X-Forwarded-For from the first proxy hop. |
RELATA_CORS_ALLOWED_ORIGINS | — | Comma-separated allowed CORS origins and CSRF guard allowlist. Both layers read this single var on every profile. When unset: server/cluster block all cross-origin requests and CSRF protection is disabled (warn); free defaults to a localhost-only allowlist (localhost/127.0.0.1 on ports 3000/9090/5173) tuned for local frontend dev. E.g. https://app.example.com,https://admin.example.com. |
RELATA_DISKANN_SECTOR_CACHE_MB | 256 | Size (MB) of the process-wide LRU cache of recently-read disk-resident ANN graph sectors. Has no effect unless RELATA_DISKANN_DISK_RESIDENT=true. |
RELATA_DISKANN_IO_BUDGET | 512 | Max sector reads per true-disk vector search query before the search stops early — see RELATA_DISKANN_IO_FAIL for what happens then. Has no effect unless RELATA_DISKANN_DISK_RESIDENT=true. |
RELATA_DISKANN_RERANK_FACTOR | 6 (or RELATA_DISKANN_PROFILE's rerank_factor) | Multiplier controlling how many coarse candidates the true-disk vector search's rerank pass re-scores exactly against full vectors, per requested k. Clamped to ≥ 1. Has no effect unless RELATA_DISKANN_DISK_RESIDENT=true. |
RELATA_DISKANN_IO_FAIL | open | open (default) returns the current best-k results when RELATA_DISKANN_IO_BUDGET is exhausted; closed returns an empty result instead of a partial one. Has no effect unless RELATA_DISKANN_DISK_RESIDENT=true. |
RELATA_STREAM_REAUTH_INTERVAL_SECS | 15 | How often a live change-stream connection (GET /graph/changes, GET /changes) re-checks the credential that opened it, for the life of the (potentially indefinite) SSE stream. The stream ends the moment a re-check fails, bounding how long a revoked/expired token keeps delivering events. |
RELATA_DELETE_MAX_ROWS_PER_STATEMENT | 50000 | Max rows one DELETE FROM statement tombstones before returning. A call that hits the cap tombstones the first N matching rows and reports the rest via the response's remaining field — re-issue the same statement to continue; already-tombstoned rows are excluded from the next call, so repeated calls always finish. 0 disables the cap. |
RELATA_RECURSIVE_CTE_MAX_ROWS | 100000 | Cumulative row cap for WITH RECURSIVE materialization. A self-joining recursive term can multiply rows per iteration, so an iteration-count cap alone doesn't bound memory. 0 disables the cap. |
RELATA_MAX_EXPORT_ROWS | 1000000 | Hard ceiling on GET /export row-version count, mirroring RELATA_MAX_RESULT_ROWS for the /query path. 0 disables the cap — not recommended for large tables, since export materializes its full result in memory rather than streaming it. |
RELATA_MAX_OWL_REASONER_EDGES | 200000 | Hard ceiling on the number of live graph edges handed to the OWL reasoning kernel per CHECK CONSISTENCY/INFER INVERSES/INFER CHAINS call, so an ordinary query-capable user can't force an unbounded synchronous reasoning pass. 0 disables the cap. |
Ingest and query
| Variable | Default | Description |
|---|---|---|
RELATA_INGEST_PARTITIONS | — | Number of parallel ingest write partitions. |
RELATA_INGEST_QUEUE_MAX_BYTES | 1073741824 (1 GiB) | Byte budget for queued (not-yet-drained) ingest batches. Backpressure (HTTP 429) fires when EITHER the batch count (10,000) OR this byte budget would be exceeded — so a handful of very large batches can't admit hundreds of GB before the store-side cap sees them. 0 disables the byte check (count-only backpressure). |
RELATA_INGEST_QUEUE_LANES | Detected CPU cores, clamped 1..=64 | Number of independent lock domains ("lanes") the ingest queue shards into (adaptive sizing). Each lane owns its own deque + content-hash dedup window, so producers routed to different lanes (by a stable hash of object_type + tenant) never contend on the same mutex. capacity/RELATA_INGEST_QUEUE_MAX_BYTES and per-tenant quota stay global regardless of lane count. Parsed strictly — a non-integer value fails startup. |
RELATA_INGEST_SHED_PCT | 80 | Queue-depth % at which the node sheds ingest: /health/ready returns 503 ("ingest queue backpressure") and the readiness gate fails. Clamped to 1..=100; out-of-range/unparseable falls back to 80. The last previously-hardcoded ingest-shed knob (complements the byte/count caps above). |
RELATA_SEQUENCE_RULE | — | Comma-separated spec for the sequence-correlation detection job's steps (e.g. A→B,window=300). Unset = default rule. |
RELATA_AUTO_REGISTER_TYPES | — | Set true to create new types on first ingest without prior DDL. |
RELATA_GLOBAL_SCAN_ALLOWED | — | Set true to allow full-table scans (expensive on large datasets). |
RELATA_MV_MAX_ROWS | — | Max rows per materialized view partition. |
RELATA_FACET_SCAN_LIMIT | 100000 | Row ceiling for FACETS aggregation. When a query requests facets, its LIMIT is bumped to at least this many rows so facet counts reflect the full matching set rather than just the top-k; the same value short-circuits the per-row facet-counting loop even if the caller's own LIMIT was larger. Lower it on smaller deployments to cut the bumped-scan cost; raise it for accurate facets over larger match sets. |
RELATA_AUDIT_SHARDS | 8 | Number of independent hash-chain shards for the audit log, clamped to [1, 256]. Each shard has its own lock, so push throughput scales with core count. Set to 1 to reproduce the legacy single-chain behavior exactly -- the setting to use when a compliance requirement demands one global total order. |
RELATA_FTS_MAX_DOCS | 5000000 on server/cluster profiles; unbounded on free | Max documents held in the full-text search index before the spill trigger fires. Set explicitly to override the profile default. |
RELATA_FTS_MAX_TERMS | 5000000 | Max unique terms in the full-text dictionary. Past this cap, new terms are silently dropped so the dictionary stays below ~200 MB even under high-cardinality OCR/log/social-media ingest. |
RELATA_FTS_DOC_CACHE_MAX | 100000 | Max snippet-text entries held in the in-memory doc_text cache. The oldest entry is evicted on overflow so the cache stays bounded; a cache miss yields an empty snippet (never a crash). Set to 0 to disable the cap entirely. |
RELATA_FTS_RESIDENT_TEXT | false | Whether the full-text index keeps a resident copy of every indexed document's text for snippet generation. Off by default: a search hit's snippet is instead resolved lazily from the row store, for the surviving limit hits only -- the row table already holds the text, so the default path never stores it twice. Set to true to restore the legacy resident-snippet behavior (marginally faster for small corpora that query heavily). Strict bool_env parse. |
RELATA_FTS_SHARDS | 1 | Number of independently-locked segments each per-type full-text index fans documents/queries out across. A document routes to shard hash(id) % N; a write only takes that one shard's lock, so a reader on any other shard is never blocked by concurrent indexing, and a query is scored across all N shards in parallel. BM25 IDF and length normalization stay corpus-global regardless of N (shared n_docs/total_doc_len/per-term df), so the default 1 (today's single-lock behavior, unchanged) and any N > 1 return identical rankings -- only the RAM layout and concurrency characteristics differ. Clamped to at least 1; malformed/0 values fall back to 1. Strict parse_env_u64_or. |
RELATA_WAND_OFFSET_THRESHOLD | 1000 | Minimum offset value at which preset_search_with_options switches from standard WAND to Block-Max WAND (BMW) for deep-offset pagination. BMW uses per-block BM25 upper bounds to skip entire 64-doc blocks below the current score threshold, achieving O(log N) pruning instead of O(N) scanning. Results are identical to the standard path — BMW is a safe optimisation. Set to 0 to always use BMW; set to a very large value to disable it. |
RELATA_PENDING_FTS_MAX | 1000000 | Cap on the pending full-text-index backlog (documents awaiting async FTS indexing) before new entries are dropped and counted. 0 (or unset) uses the default. |
RELATA_PENDING_INDEX_WORK_MAX | 1000000 | Cap on the pending secondary/range-index + vector-embedding backlog (rows awaiting async indexing, deferred off the insert/insert_with_prov critical path). UNLIKE RELATA_PENDING_FTS_MAX, past this cap the insert is REJECTED (StoreError::IndexQueueFull) rather than silently dropped — a dropped secondary/vector entry would permanently hide a row from index-routed queries. Unset uses the default. |
RELATA_INDEX_BACKPRESSURE_THRESHOLD | 200000 | On a RELATA_ROLE=query node only: once the deferred index-work queue (spilled-or-unconfirmed rows, ObjectStore::pending_secondary_work_queue_len) reaches this depth, ingest doors (/ingest, OTLP traces/logs/metrics, schemaless) return HTTP 429 with a Retry-After hint instead of accepting more writes — protects against an unbounded backlog when the RELATA_ROLE=indexer node is slow or down. No-op on RELATA_ROLE=both/indexer. |
RELATA_INDEX_BACKPRESSURE_DISABLED | false | Set true to opt a RELATA_ROLE=query deployment out of the RELATA_INDEX_BACKPRESSURE_THRESHOLD 429 shedding above — writes are accepted regardless of backlog depth. |
RELATA_ANN_EAGER | — | Set true to eagerly load ANN index into RAM at startup. |
RELATA_RULE_EVAL_INTERVAL_SECS | — | How often the rules engine re-evaluates derived facts. |
RELATA_DETECTION_JOBS_INTERVAL_SECS | — | Detection job sweep interval. |
RELATA_JOBS_MAX_PARALLEL | 4 | How many (job, tenant) detection-scan units run concurrently on the blocking pool per scheduler tick. |
RELATA_JOBS_TRIGGER_DEBOUNCE_MS | 500 | Debounce window for an event-triggered detection job — how long to wait after the first commit to a subscribed object type before running, so a burst of commits coalesces into one run instead of one per commit. |
RELATA_JOBS_TRIGGER_POLL_MS | 200 | How often detection_jobs_task re-checks pending event-triggered jobs even with no fresh commit notification, bounding the worst-case delay between a debounce window elapsing and the job being observed due. Not the primary wake-up path — that is the storage layer's commit Notify. |
RELATA_WORKFLOW_DRIVER_INTERVAL_SECS | 1 | How often (seconds) the background workflow driver advances in-flight workflow executions. |
RELATA_WORKFLOW_STEP_TIMEOUT_SECS | — | Per-run wall-clock timeout (seconds). If set and a run exceeds it between step batches, remaining pending steps are marked failed and a dead-letter alert fires. Unset = no timeout. |
RELATA_WRITE_CONCERN | one | Replication write concern: one (fire-and-forget, default), quorum (wait for majority of peers), all (wait for all peers). Non-one values bound RPO under failure at the cost of write latency. Startup fails on any other value (a typo previously silently downgraded to one). |
RELATA_DETECT_PACKS | — | Comma-separated detector packs to activate. |
RELATA_DETECT_BATCH_SIZE | 256 | Chunk size for batched identity detection (SmartIngest::detect_batch_with). Inputs are detected in chunks of this many so the per-input setup and a reused hit buffer are amortised across the chunk instead of one synchronous detect_with per cell. Non-positive / unparseable values fall back to 256. Detection results are identical regardless of batch size; this only tunes throughput. |
RELATA_FK_EDGES | — | Comma-separated FK-to-edge mappings: TypeName.field=predicate,... (e.g. CdrRecord.tower_id=uses_tower,TransactionGraph.from_wallet=sends_to). At ingest time each matching FK field is materialised as a KnowledgeTriple row so PATHS_BETWEEN can traverse typed-object→graph boundaries without schema changes. |
RELATA_IDENTITY_LINK | — | Comma-separated identity-link mappings: TypeName.field=predicate,... (e.g. CdrRecord.caller_msisdn=has_msisdn). At ingest time the field value is materialised as a KnowledgeTriple with the given predicate. Use identity-semantic predicates (has_msisdn, has_email, identified_by, linked_to) to make the link visible through lookup_identity. |
RELATA_INGEST_LATE_ARRIVAL | false | Master switch for the ingest late-arrival gate. When true, drained batches are classified against an event-time watermark and late batches are routed per RELATA_INGEST_LATE_POLICY. Default false leaves ingest unchanged — appropriate only for genuinely streaming sources, never backfill/replay ingest. |
RELATA_INGEST_LATE_POLICY | drop | What happens to a batch the late-arrival gate classifies as late: drop (discard, counted), dlq (preserve every row in the dead-letter sink), or reprocess (retroactive insert). Only read when RELATA_INGEST_LATE_ARRIVAL=true. Any other value fails startup. |
RELATA_INGEST_WATERMARK_BOUND_NS | 5000000000 (5s) | Out-of-order bound, in nanoseconds, for the ingest watermark generator: events arriving within this bound of the latest observed event time are still treated as on-time. |
RELATA_INGEST_LATE_WINDOW_NS | — | Optional window size (ns) used by the reprocess late-arrival policy to log the affected window. Unset means no window layout is assumed. |
RELATA_INGEST_DLQ_PATH | {data_dir}/ingest-dlq.ndjson | NDJSON dead-letter sink for batches routed there by RELATA_INGEST_LATE_POLICY=dlq — one JSON line per row, replayable. With no data directory and no override, dlq degrades to a counted drop. |
RELATA_INGEST_WRITER_SHARDS | 1 | Number of intra-type row shards the background ingest writer's insert phase fans out across. 1 (default) is fully sequential for a single hot type. Effective fan-out is capped by the type's real storage shard count (RELATA_TABLE_GC_SHARDS/_AUTO) — raising this alone, without also raising that, adds no parallelism and can be slower. Clamped to [1, 64]. |
RELATA_MV_CHANGE_LOG_ENABLE | false | Enables recording every touched row into a bounded per-type change-tracking log for a future materialized-view incremental-refresh feature. Off by default — pure overhead with no consumer of the log yet. |
RELATA_MV_CHANGE_LOG_MAX_ROWS | 10000 | Per-type cap on buffered row IDs in the change-tracking log above before that type's shard starts dropping entries. Only meaningful when RELATA_MV_CHANGE_LOG_ENABLE=true. |
RELATA_AUDIT_LOG_WARN_MB | 1024 | Size threshold in MB above which the background audit verifier logs a warning that audit.jsonl is large. Rotation is separate and opt-in (RELATA_AUDIT_SEGMENT_MAX_MB), so the audit log still grows unbounded by default. 0 disables the warning; the size gauge on /metrics keeps updating regardless. |
RELATA_AUDIT_SEGMENT_MAX_MB | 0 (disabled) | Size threshold in MB above which the audit log automatically rotates to a numbered segment and a fresh live file opens. 0 (default) disables rotation. Rotated segments replay transparently into one continuously verified chain on restart, and are never deleted automatically. |
RELATA_FTS_MAX_RESIDENT_BYTES | unset (disabled) | Byte-budget complement to RELATA_FTS_MAX_DOCS for automatic full-text cold-tier spilling. When set, a type's estimated resident memory is also checked against this ceiling — crossing either budget evicts the largest resident type to disk. |
RELATA_FTS_POSITIONS | true | Whether the full-text index maintains the positional index PHRASE search verifies token adjacency against — costs roughly 8x the source-text size. With positions off, PHRASE falls back to re-tokenizing resident text (needs RELATA_FTS_RESIDENT_TEXT=true); with both off, PHRASE queries against the affected type return zero matches. |
RELATA_FTS_SHARD_GROW_THRESHOLD | 10000 | Live-document-count threshold at which a per-type full-text index (which always starts at 1 shard) migrates in place to the target shard count (RELATA_FTS_SHARDS). A small corpus that never crosses this stays at 1 shard; migration is a one-time blocking pass. |
RELATA_FTS_PARALLEL_FANOUT_THRESHOLD | 10000 | Total live-document-count threshold at/above which a full-text query fan-out dispatches shards onto the parallel worker pool instead of walking them serially. Below this size, parallel dispatch overhead makes queries slower. 0 disables parallel fan-out. |
RELATA_FTS_TRIGRAM_CANDIDATE_CAP | 20000 | Caps the number of distinct dictionary terms fuzzy/prefix/suffix/infix full-text search draws from the trigram index per query before verification. Bounds worst-case query cost; never produces a false positive, only trades recall in a rare pathological case. |
RELATA_PENDING_FTS_OVERFLOW_MAX | 1000000 | Cap on the second-chance queue a pending full-text-indexing doc overflows into when the main pending-FTS queue is full. Docs are pulled back in as the main queue drains; row storage/durability is unaffected either way. 0 disables the second-chance tier. |
RELATA_FTS_COLD_TIER_COMPACT_POSTINGS | false | Opt-in switch of the disk-spilled full-text "cold tier" posting-list format to a more compact blocked encoding. Purely an at-rest format choice — query results and in-memory representation are unaffected. Off by default. |
RELATA_FORGET_SCHEDULER_INTERVAL_SECS | 60 | How often the background forget-scheduler tick runs (scans due retention marks and retracts matching rows). Widen on deployments with large tenant counts to reduce per-tick cost. |
RELATA_RETENTION_ENFORCER_INTERVAL_SECS | 60 | How often the background retention-enforcement tick runs (scans active retention policies and retires over-age rows). Widen on deployments with large tenant/policy counts. |
RELATA_SUMMARY_TREE_INTERVAL_SECS | 21600 (6h) | How often the background summary-tree builder rebuilds the precomputed thematic-search summary tree POST /rag/query's search_mode: thematic reads. A batch rebuild, not a low-latency sync. |
RELATA_COMMUNITY_ASSIGNMENT_INTERVAL_SECS | 21600 (6h) | How often the background entity-community-assignment builder rebuilds graph-community-based summary rows, the GraphRAG-parity counterpart to RELATA_SUMMARY_TREE_INTERVAL_SECS, both readable via POST /rag/query's search_mode: thematic. |
RELATA_RYW_STALENESS_WINDOW_MS | 500 | Window in milliseconds after a WriteConcern::One peer-replicated write during which a cluster fan-out read of that type is stamped with a consistency advisory noting the response may be missing or stale. Session-blind and process-local. 0 disables it; only active under RELATA_WRITE_CONCERN=one. |
RELATA_DETECT_TYPE_PACKS | — | Semicolon-separated per-type detector-pack overrides, e.g. Transaction=financial,contact;Vessel=transport;LogEvent=none. A type with no override falls back to the global RELATA_DETECT_PACKS config. Also settable at runtime via POST /types/detect-config. |
RELATA_IDENTITY_MIN_CONFIDENCE | 1.0 | Minimum detection confidence (0.0-1.0) required before a detected identity is written into the authoritative identity index backing SAME_IDENTITY/RESOLVE_IDENTITY/LOOKUP_IDENTITY. Default 1.0 admits only checksum-verified hits; lower it to admit heuristic hits once you've accepted the false-attribution risk. Out-of-range values are clamped. |
RELATA_DETECT_MAX_TOKEN_LEN | 4096 | Upper bound in bytes on a single token identity detection will run through any eager gate. Prevents one giant unwhitespaced field from dominating detection cost on the request thread. |
RELATA_IDENTITY_ACTIVE_LEARNER_MAX_HISTORY | 10000 | Cap on the active-learner's label history (a ring buffer, oldest evicted first). Bounds save cost for POST /identity/label/GET /identity/uncertainty. |
RELATA_IDENTITY_DISAMBIGUATION_FLOOR | 0.8 | Minimum top-candidate confidence (0.0-1.0) required before an entity-name lookup auto-resolves to a single candidate; below this floor the candidate is surfaced for disambiguation instead. |
RELATA_IDENTITY_DISAMBIGUATION_GAP | 0.3 | Minimum score gap between the top candidate and runner-up required before auto-resolving; below this gap, candidates are treated as within margin and surfaced as ambiguous. |
RELATA_IDENTITY_DISAMBIGUATION_MAX_CANDIDATES | 5 | Cap on how many candidates the disambiguation "ambiguous" outcome surfaces, highest-scored first. |
Observability
| Variable | Default | Description |
|---|---|---|
RELATA_LOG_LEVEL | info | Log verbosity: error | warn | info | debug | trace. |
RELATA_LOG_FORMAT | TTY-detect | Log format: pretty (human-readable) | json (structured). Defaults to pretty when stderr is a TTY, json otherwise. Note: the CLI binary defaults to pretty format; containers should explicitly set RELATA_LOG_FORMAT=json for structured log ingestion. |
RELATA_OTLP_ENABLED | false | Set true to enable native OTLP HTTP ingest endpoints (POST /v1/traces, /v1/metrics, /v1/logs). Disabled by default; off-the-shelf OTLP exporters (Jaeger, Tempo, Grafana Alloy) will receive 404 until enabled. |
RELATA_OTLP_ENDPOINT | — | OpenTelemetry OTLP/HTTP endpoint. Telemetry disabled when unset. |
RELATA_OTLP_SAMPLE_RATIO | 0.01 | Parent-based TraceID-ratio sampler for root traces (1% default). |
RELATA_METRICS_PUBLIC | — | Set true to serve /metrics without the bearer check (auth terminated at the network layer). Default fails closed. |
RELATA_PROFILE_SAMPLE_RATE | 0.01 | Fraction ([0.0, 1.0]) of production queries that get per-operator attribution (scan/filter/join/aggregate/sort/acl/serialize timing, feeding /metrics — see the flamegraph guide). 0.0 disables sampling entirely; EXPLAIN ANALYZE always instruments regardless of this setting. Malformed or out-of-range values fail startup. |
RELATA_PPROF_ENABLE | false | Enable GET /debug/pprof/profile (CPU pprof protobuf, ?seconds=1..30) and GET /debug/pprof/heap. Off by default — a profiling endpoint is an attack surface (leaks workload shape + internal symbol names). When enabled, both routes additionally require RELATA_ADMIN_TOKEN to be set and a matching Authorization: Bearer on every profile, including the free profile where the general bearer check is otherwise optional — there is no dev bypass for this surface. See the flamegraph guide. |
RELATA_OBSERVE_STREAM | false | Enables the live structured observability event stream at GET /observe/stream (SSE). When on, every protocol-door query's lifecycle is published as a typed JSON event carrying door, purpose, tenant, trace ID, stage, row count, latency, and error. Tenant-scoped server-side. |
Cluster
| Variable | Default | Description |
|---|---|---|
NODE_ID | node-1 | Cluster node identifier. |
NODE_ADDR | — | This node's advertised address (host:port) for peer-to-peer communication. |
NODE_REGION | — | Region label for geo-aware routing. |
CLUSTER_PEERS | — | Comma-separated peer URLs. Empty = standalone mode. |
CLUSTER_ROLE | coordinator | Node role: coordinator | reader | writer | indexer (routing/registry hint, not a hard access gate — see Cluster Setup for what each role means). An unrecognized value fails startup. |
RELATA_ROLE | both | Indexing-placement role: query | indexer | both (crates/relata-cli/src/serve.rs). Independent of CLUSTER_ROLE above (that one drives query fan-out routing; this one drives where deferred secondary/range/vector index-maintenance work — relata-storage's pending_index_work queue — is applied). both (default) preserves the legacy behaviour: the index-work-drain background task applies deferred work inline, on this node. query spills that work to a pending-index/ object-store prefix instead (falls back to inline drain with a loud warning if no remote store is configured) so a heavy bulk-index workload never touches this node's CPU. indexer runs a dedicated worker loop (crates/relata-cli/src/serve/indexing_worker.rs) that claims and applies spilled work items via an S3 conditional-put lease (relata_cluster::WriteCoordinator::try_claim_index_work_item); this task is otherwise idle. |
CLUSTER_COORDINATOR | — | Coordinator URL for leader election. |
CLUSTER_DISCOVERY | — | Discovery mechanism (static | dns | k8s). |
CLUSTER_AUTH_TOKEN | — | Shared token for inter-node gRPC authentication. |
RELATA_GRPC_REQUEST_TIMEOUT_SECS | 30 | Default per-RPC timeout (seconds) on the cluster gRPC client pool. Applies to every inter-node RPC unless overridden per-call; a stuck peer returns DeadlineExceeded instead of hanging the caller. |
RELATA_CLUSTER_SHARDS | 8 | Consistent-hash shard count. Must be identical on every node. |
RELATA_CLUSTER_SEED | — | Shared seed for partition key derivation (alternative to explicit K0/K1). |
RELATA_CLUSTER_DEAD_AFTER_SECS | 90 | Seconds without a heartbeat before a node is evicted. |
RELATA_CLUSTER_REBALANCE_TIMEOUT_SECS | — | Max time allowed for a rebalance operation. |
RELATA_MAX_REPLICATION_LAG | 10000 | Replica readiness gate: when this node is a replica (reader role) and its replication lag (frontier − applied WAL sequence units) exceeds this, /health/ready returns 503 so the replica is drained from the read path before it serves stale data. Current lag is also exported as the relata_replication_lag Prometheus gauge and in the readiness JSON. 0 disables the gate. Non-replica / single-node deployments are unaffected. Prometheus metrics: relata_replication_lag (this node, WAL sequence units), relata_replication_lag_seconds (slowest follower, wall-clock seconds), relata_replication_lag_seconds_by_replica{replica_id} (per-replica WAL sequence units). Alert RelataReplicaLagHigh fires when any replica exceeds 30 sequence units for 5 minutes. |
RELATA_MULTI_REGION | — | Set true to enable multi-region active-active mode. |
RELATA_CLUSTER_BRANCH | main | Branch this node stamps on fenced write-leases and /internal/replicate batches (cluster profile). |
RELATA_LEASE_TTL_MS | 30000 | Fenced write-lease TTL in milliseconds (cluster profile). Renewed every ttl/3; a missed renewal loses the lease. |
RELATA_PARTITION_KEY_K0 | — | First u64 half of the 128-bit SipHash partition key. Both halves required when set. |
RELATA_PARTITION_KEY_K1 | — | Second u64 half of the 128-bit SipHash partition key. |
RELATA_GRPC_DIAL_MAX_ATTEMPTS | 3 | Max inter-node gRPC dial attempts before giving up (clamped 1–10). |
RELATA_GRPC_DIAL_BACKOFF_MS | 50 | Base backoff between gRPC dial attempts (exponential, ms). |
RELATA_GRPC_BREAKER_THRESHOLD | 5 | Consecutive failures before the per-peer gRPC circuit breaker opens (clamped 1–100). |
RELATA_GRPC_BREAKER_COOLDOWN_MS | 5000 | Cooldown before a tripped gRPC circuit breaker probes the peer again. |
RELATA_HEDGE_ENABLED | false | Set true/1/yes/on to hedge scatter-gather reads (send a backup request after a delay). |
RELATA_HEDGE_DELAY_MS | 50 | Delay before issuing the hedged backup request when hedging is enabled; also the floor/fallback delay when a peer has no LatencyTracker samples yet. |
RELATA_HEDGE_PERCENTILE | 0.95 | When a LatencyTracker is wired, the hedge backup fires after this percentile of the target peer's own recently-observed latency instead of the fixed RELATA_HEDGE_DELAY_MS, floored at that delay. Clamped to [0.0, 1.0]. |
RELATA_PARTITION_STRATEGY | hash | Cluster row-partition strategy (crates/relata-cluster/src/partition.rs). hash (default, consistent-hash over the row key) | smart-graph (co-locates graph-connected rows). Unknown values fall back to hash with a warning log. |
RELATA_BRANCH_SHARD_REGION | — | Opt-in: when set to a non-empty region name, constructs a BranchShardCoordinator that makes the CROSS_SHARD_WRITE guard load-bearing — a governed write whose _target_branch names a branch owned by a different shard is rejected instead of silently accepted. Unset (default) = no-op guard, every deployment unaffected. |
RELATA_BRANCH_SHARD_CASE | main | Case/branch-family name used to derive this shard's owned branch alongside RELATA_BRANCH_SHARD_REGION (BranchShard::branch_name_for). Only read when RELATA_BRANCH_SHARD_REGION is set. |
RELATA_CROSS_REGION_PEERS | — | Comma-separated region=addr pairs declaring cross-region merge peers, e.g. eu=https://eu.example:9443,apac=https://apac.example:9443. Only read when RELATA_BRANCH_SHARD_REGION is set; populates BranchShardCoordinator.remote_shards so the cross-region merge scheduler (below) has peers to fetch from. Malformed entries are skipped with a warning; unset/empty keeps the prior single-node default (no peers), and the merge scheduler no-ops every tick. |
RELATA_CROSS_REGION_MERGE_INTERVAL_SECS | 60 | Interval for the supervised cross-region merge background task that calls run_merge_cycle_gated. Strictly parsed — a malformed value fails startup. No-ops (logs at debug and skips the cycle) when RELATA_BRANCH_SHARD_REGION/RELATA_CROSS_REGION_PEERS are unset, or when RELATA_MULTI_REGION is off. |
RELATA_GRPC_CONNECT_TIMEOUT_MS | 5000 | Connect-phase bound applied to every dial made by the pooled cluster gRPC transport (the plain-SQL cluster fan-out's live transport). 0 disables the bound. |
RELATA_CLUSTER_CONNECT_TIMEOUT_MS | 5000 | Connect-phase bound applied to the direct (unpooled) cluster gRPC client used by the heartbeat loop, coordinator election, and vector/FTS shard fan-out. Bounds only the handshake, not the RPC itself. 0 disables the bound. |
RELATA_CLUSTER_HEARTBEAT_PEER_TIMEOUT_MS | 5000 | Per-peer bound on one heartbeat round's dial + RPC. Peers are dialed concurrently, so one dead peer cannot delay heartbeat delivery to the others. 0 disables the bound. |
RELATA_CLUSTER_ELECTION_PEER_TIMEOUT_MS | 5000 | Per-peer bound on one coordinator-election round's dial + yield-request. An unreachable higher-priority peer is treated as not-yielded once the bound elapses. 0 disables the bound. |
RELATA_CLUSTER_SHARD_QUERY_TIMEOUT_MS | 10000 | Per-shard bound on one cluster vector/FTS search fan-out call. A shard that connects and then stalls surfaces as a normal failed-shard entry instead of stalling the whole fan-out. 0 disables the bound. |
RELATA_CLUSTER_VIRTUAL_NODES_PER_NODE | 150 | Virtual-node count per physical node on the consistent-hash ring. Higher values improve distribution uniformity at the cost of more ring entries. Must be identical on every node — a mismatch produces divergent ring placement, not currently detected at handshake. |
RELATA_CLUSTER_MAX_CONCURRENT_MOVES | 10 | Maximum concurrent partition moves processed per batch during rebalancing. Rate-limits I/O pressure on source/target nodes; raise it on a larger, higher-throughput cluster. |
RELATA_CLUSTER_MAX_VIRTUAL_SPLIT | 256 | Maximum number of sub-partitions a single physical partition can be split into for hot-key splitting. Splits are in-memory only — raising this ceiling doesn't make a split durable across a restart. |
RELATA_REPLICATION_FACTOR | 3 | Number of distinct node owners resolved for a given key under owner-routed replication. Must be identical on every node. Also acts as the ring's under-replication floor: the ring stays empty (falling back to full-mirror replication) until at least this many live members are observed, so a cluster with fewer nodes than this value never uses owner-routed placement at all. |
RELATA_REPLICATION_CHUNK_ROWS | 1000 | Rows per outbound peer-replication request from the ingest-writer's drain fan-out. Bounds request size so a large drain cycle can't blow past the replication client's request timeout or starve a small node's worker threads. Chunks are sent sequentially per peer; peers stay parallel with each other. |
RELATA_REPLICATION_MAX_BATCH_ROWS | 20000 | Row-count cap the replication receiver enforces on an inbound replication request, checked before any row is processed — a defense-in-depth backstop against an oversized batch from an older peer or a sender regression, independent of the sender-side RELATA_REPLICATION_CHUNK_ROWS cap. A batch over the cap is rejected outright rather than processed. |
RELATA_REJECT_NON_OWNER_WRITES | false | Off by default: a write landing on a node the replica-owner ring does NOT list as an owner is still silently accepted and stored locally. Set true to make strict owner placement a hard guarantee — such a write is refused outright (HTTP 421) so the caller retries against a real owner, logged and audited. Fails open (falls back to accept-locally) whenever ownership can't be resolved with full confidence, since a wrongly-rejected write would be a write-availability regression. |
RELATA_STABLE_RING_SETTLE_SECS | 60 | Settle window the rebalancer requires the target replica-ownership ring to have gone unchanged (with no partition move still pending) before promoting it to the stable ring. Until promoted, both the old and new ring's owner sets are honored, so a node that legitimately held a key's history around a membership change isn't silently dropped from the owner set. |
RELATA_CLUSTER_AUTO_SPLIT_SIZE_BYTES | 0 | Size threshold at which a locally-owned partition is automatically split by a periodic background tick. 0 (default) disables auto-split — a partition still splits via the manual split endpoint until this is set. |
RELATA_CLUSTER_AUTO_SPLIT_COOLDOWN_SECS | 600 | Cooldown window after a partition auto-splits before it (or a resulting sub-partition) is eligible to auto-split again, preventing a split storm from a noisy size estimate. Only meaningful when RELATA_CLUSTER_AUTO_SPLIT_SIZE_BYTES is nonzero. |
RELATA_FLEET_CACHE_BUDGET_BYTES | 0 | Fleet-wide cache-budget total in bytes, apportioned across cluster nodes by role and recomputed on every membership change. 0 (default) means no fleet budget is declared — each node keeps its own node-local default. |
RELATA_PARTITION_MAP_PATH | — | Path to a local durable log backing the cluster move-coordinator's partition map, so a coordinator restart recovers prior partition-ownership state instead of losing it. When unset, falls back to the shared object store (if configured), else a process-local, non-durable map. FATALs at startup if set but the path fails to open. |
RELATA_PARTITION_MAP_MAX_SNAPSHOTS | 64 | Cap on the number of per-commit deltas retained in the object-store-backed partition map before they're folded into a fresh full-state checkpoint. Keeps the manifest bounded regardless of total dataset size. 0 = unbounded delta retention (no compaction ever happens). |
RELATA_REPLICATION_ALLOWED_REGIONS | — | Comma-separated region-label allowlist consulted by every peer-replication write and cross-region-merge fan-out before dialing a remote region. A peer/region NOT in this list is denied. Unset (with the denylist also unset) means no restriction. |
RELATA_REPLICATION_DENIED_REGIONS | — | Comma-separated region-label denylist for the same replication placement policy as RELATA_REPLICATION_ALLOWED_REGIONS — a peer/region in this list is always denied regardless of the allowlist. A denied peer is never dialed. |
RELATA_REPLICATION_GEOFENCE_REASON | operator-configured geo-fence (...) | Human-readable reason string stamped on the replication placement policy and surfaced in logs when a peer or region is denied (e.g. "GDPR: eu-west-1 must not receive PII"). Only meaningful when at least one region allow/deny-list is set. |
LLM and AI inference
| Variable | Default | Description |
|---|---|---|
RELATA_LLM_URL | — | LLM API base URL (OpenAI-compatible). Also accepted by OPENAI_BASE_URL for compatibility. |
RELATA_LLM_BACKEND | — | Native LLM backend: bedrock | gemini | huggingface. Leave unset for OpenAI-compatible HTTP (the default). |
RELATA_LLM_API_KEY | — | LLM API key. |
RELATA_LLM_PROVIDER | — | LLM provider hint. May be a name (openai | anthropic | google | hf | bedrock) or an endpoint URL. Read by the LLM dispatcher (crates/relata-cli/src/serve/config.rs) and the config --migrate map. |
RELATA_LLM_MODEL | — | Model name/ID to use. |
RELATA_LLM_TIMEOUT_MS | — | LLM request timeout in milliseconds. |
RELATA_INFERENCE_BACKEND | — | Inference accelerator backend (separate dispatch path from RELATA_LLM_BACKEND). |
RELATA_NL_REQUIRE_LLM | false | Set true to reject natural-language (nl_query) requests when no LLM is configured instead of falling back to the heuristic parser. Startup fails on unrecognised values. |
RELATA_EMBED_URL | — | Canonical embedding sidecar HTTP endpoint. Used by both the HTTP embedder (RELATA_EMBEDDER=http) and the media-worker learned-model path. E.g. http://localhost:8080/embed. Since v1.1 the ingest hot path no longer embeds text rows — set this so the media-worker drain cycle populates embeddings asynchronously after write returns (see embedder sidecar). Without it, the built-in CPU embedder (128-dim, deterministic) is used query-side only. Image/audio/video also need RELATA_DECODER_ENDPOINT. (RELATA_ACCEL_ENDPOINT is a deprecated alias — see the Deprecated section.) |
RELATA_DECODER_ENDPOINT | — | Media decoder sidecar HTTP endpoint. When unset, the media worker refuses to index media (no decode → no perceptual hashes → no embedding) rather than ship non-semantic fallback vectors. |
RELATA_BEDROCK_URL | — | AWS Bedrock endpoint URL. |
RELATA_BEDROCK_API_KEY | — | AWS Bedrock API key. |
HF_ENDPOINT | — | HuggingFace Inference Endpoints URL. No RELATA_ prefix — read directly (upstream SDK convention; crates/relata-intelligence/src/llm.rs). |
HUGGINGFACE_API_KEY | — | HuggingFace API key. No RELATA_ prefix — read directly (upstream SDK convention; crates/relata-intelligence/src/llm_adapters.rs). |
GOOGLE_API_KEY | — | Google Gemini API key. No RELATA_ prefix — read directly (upstream SDK convention; crates/relata-intelligence/src/llm_adapters.rs). |
RELATA_EMBEDDER | — | Embedder type (local | openai | hf | http | onnx). |
RELATA_EMBED_MODEL | — | Embedding model name. |
RELATA_EMBED_API_KEY | — | Optional bearer token sent to the HTTP embedding endpoint when RELATA_EMBEDDER=http (crates/relata-storage/src/embedder.rs). Unset = no auth header. |
RELATA_LLM_MAX_PROMPT_CHARS | 16384 | Byte cap on any single caller-controlled prompt-building input before it is embedded into a prompt sent to a configured external LLM endpoint. Oversized input is truncated (not rejected), logged for audit. Mirrors the embeddings pipeline's 16 KiB input-too-long cap. |
RELATA_LLM_PROVIDER_TIMEOUT_MS | 30000 | Timeout bound for the native LLM provider adapters (Bedrock, Gemini, HuggingFace, and the OpenAI-compatible env adapter). Without it a hung provider endpoint could block a caller thread indefinitely. |
RELATA_LLM_MAX_CONCURRENCY | 8 | Cap on in-flight LLM text-completion calls across every provider adapter, independent from RELATA_EMBED_MAX_CONCURRENCY (the embed/rerank sidecar is typically local/unmetered; LLM completion providers are typically paid, rate-limited SaaS APIs). A burst of calls queues at this bound instead of fanning out unboundedly. Must be ≥ 1. |
RELATA_LLM_BREAKER_THRESHOLD | 5 | Consecutive LLM-provider call failures that open the shared circuit breaker — subsequent calls fail fast to the local fallback instead of each paying the full timeout. Must be ≥ 1. |
RELATA_LLM_BREAKER_COOLDOWN_MS | 10000 | How long the LLM circuit breaker stays open before a half-open probe call. |
RELATA_DECODER_TIMEOUT_MS | 30000 | Timeout bound for calls to the decoder sidecar (used by perceptual-hash ingest), mirroring RELATA_EMBED_TIMEOUT_MS. |
RELATA_EMBED_MAX_CONCURRENCY | 8 | Cap on in-flight inference-engine calls (embed + rerank combined). An ingest burst behind a slow engine queues callers at this bound instead of fanning out unboundedly. Must be ≥ 1. |
RELATA_INFERENCE_FAILURE_MODE | degrade | Engine-down behavior: degrade (serve lexical/RRF results, mark degraded) or fail (typed errors for inference-requiring queries). Any other value fails startup. |
RELATA_INFERENCE_BREAKER_THRESHOLD | 5 | Consecutive inference-engine failures that open the circuit breaker — calls then fail fast instead of paying the full timeout. Must be ≥ 1. |
RELATA_INFERENCE_BREAKER_COOLDOWN_MS | 10000 | How long the inference-engine circuit breaker stays open before a half-open probe call. |
RELATA_RERANK_URL | — | Dedicated cross-encoder reranker engine base URL. Falls back to RELATA_EMBED_URL/RELATA_ACCEL_ENDPOINT when unset. |
RELATA_RERANK_MODEL | — | Reranker model tag, for diagnostics only. |
RELATA_RERANK_TOP_N | 50 | Max (query, doc) pairs re-scored per rerank call — bounds the load a large fused candidate list puts on the engine. Must be ≥ 1. |
RELATA_RERANK_REQUIRED | false | true makes a RERANK request return a typed error (HTTP 400) instead of silently returning the un-reranked order when the reranker engine is missing or failing. |
RELATA_COLBERT_ENDPOINT | — | Optional ColBERT (late-interaction) reranker sidecar endpoint — same wire contract, timeout, and concurrency/breaker guard as the cross-encoder sidecar. Tried only when RELATA_RERANK_URL/RELATA_EMBED_URL/RELATA_ACCEL_ENDPOINT (the cross-encoder tier) is not configured. Genuinely optional. |
RELATA_SPLADE_ENDPOINT | — | Optional SPLADE (sparse-neural) reranker sidecar endpoint — same wire contract as the cross-encoder sidecar. Lowest-priority tier: tried only when neither the cross-encoder nor ColBERT tiers are configured. Genuinely optional. |
RELATA_SEMANTIC_CACHE_ENABLED | false | Enables the embedding-keyed result cache so a paraphrased query can hit a stored result within the similarity threshold. Covers both the plain SQL path and POST /rag/query's HYBRID_SEARCH/RAG_RETRIEVE path. Only active when a learned-semantic embedder is configured. A hit requires an exact scope match (principal/org/schema/ACL generation/bitemporal point) — similarity never widens visibility. |
RELATA_SEMANTIC_CACHE_THRESHOLD | 0.97 | Cosine-similarity threshold for a semantic cache hit (clamped to 0-1). |
RELATA_SEMANTIC_CACHE_MAX_ENTRIES | 256 | Entry ceiling for the semantic cache (LRU-evicted). Must be ≥ 1. |
RELATA_RAG_CONFIDENCE_WEIGHT_AGREEMENT | 0.6 | Weight on the channel-agreement term of POST /rag/query's per-hit relevance_confidence score — purely arithmetic over already-retrieved lexical/vector scores, no additional LLM call. |
RELATA_RAG_CONFIDENCE_WEIGHT_ENTITY_OVERLAP | 0.4 | Weight on the entity-overlap term of relevance_confidence — the fraction of the query's extracted proper-noun phrases found in the hit's chunk text. |
RELATA_RAG_STRATEGY_NARROW_SCOPE_ROWS | 500 | POST /rag/query's scope-size threshold below which the response's strategy_hint recommends lexical search mode. Advisory only — never overrides the caller's own search_mode. |
RELATA_RAG_STRATEGY_WIDE_ENTITY_SPREAD | 25 | strategy_hint's entity-spread threshold above which the hint sets widen_top_k/prefer_graph_hops to true. Advisory only. |
RELATA_RAG_GRAPH_HOP_SCAN_LIMIT | 5000 | Max rows scanned to build the entity co-occurrence graph POST /rag/query's graph_hops traverses. Bounds the cost of a hop expansion on a large corpus. |
RELATA_RAG_TWO_STAGE_MIN_CORPUS_ROWS | 2000 | POST /rag/query's automatic document→chunk two-stage routing only attempts to narrow when the requested type's live row count exceeds this threshold — below it, a flat chunk-level search is already cheap enough. |
RELATA_RAG_TWO_STAGE_CANDIDATE_DOCS | 20 | Number of candidate documents the first-pass lexical query narrows to before the two-stage chunk-level search is scoped to just their contents. |
RELATA_RAG_WINDOW_THRESHOLD | 0.15 | POST /rag/query's expand_window sentence-relevance threshold — a sentence must score at/above this (keyword overlap + entity presence) to become eligible for window expansion. |
RELATA_RAG_WINDOW_SIZE | 2 | expand_window's sentence-window half-width — a relevant sentence pulls in up to this many sentences on each side, crossing into the adjacent chunk when near a boundary. |
RELATA_RAG_WINDOW_WEIGHT_JACCARD | 0.7 | Weight on the keyword-overlap term of a sentence's expand_window relevance score. |
RELATA_RAG_WINDOW_WEIGHT_ENTITY | 0.3 | Weight on the entity-presence term of a sentence's expand_window relevance score. |
Encryption and KMS
| Variable | Default | Description |
|---|---|---|
RELATA_ENCRYPTION_AT_REST | ON for server/cluster; OFF for free | Envelope-encrypts WAL + backups. Default is profile-aware: the production server/cluster profiles encrypt-at-rest by default (fail-closed) — set false to opt out (logged loudly at startup). free stays plaintext by default; set true to enable. |
RELATA_KMS_LOCAL_DEV | false | Set true to allow the server profile to fall back to the committed dev-secret KMS backend when RELATA_KMS_KEY_ARN is not set. For local Docker dev/CI only — NEVER set in production. Logs a loud warning at startup. On server/cluster this alone is not enough — see RELATA_SECURITY_MODE above, which must also be open. |
RELATA_KMS_PROVIDER | — | KMS backend: aws | localstack | vault. |
RELATA_KMS_KEY_ARN | — | ARN of the KMS master key used for envelope encryption. |
RELATA_KMS_REGION | RELATA_REGION | KMS region. Defaults to RELATA_REGION when unset. |
RELATA_KMS_PER_TENANT | — | Set true to use distinct KMS keys per tenant/org. |
RELATA_TOKENIZE_KEY | — | 32-byte hex key for format-preserving tokenization of PII fields. |
RELATA_ERASURE_SIGNING_KEY | — (required on server/cluster) | Key used to sign erasure proofs (GDPR right-to-erasure audit trail). Since 2.4.0 a hard boot dependency on server/cluster (#4797): the erasure-proof preflight FATAL-exits at startup when the key is unset, instead of failing lazily on the first erasure request — set it before upgrading. On free, an unset value still derives a key from RELATA_BEARER_TOKEN (#1389); no action needed. Data is never at risk — only availability (the process will not start until the key is present). |
RELATA_AUDIT_HMAC_KEY | — | HMAC-SHA256 signing key for audit-log entries (crates/relata-cli/src/serve/cluster.rs). When unset, the server falls back to the RELATA_BEARER_TOKEN bytes; on server/cluster with no token configured, startup FATAL-exits (no committed default — a baked-in key would allow audit-log forgery). On free an empty key is permitted with a loud startup warning. Also used by relata audit verify for offline chain verification (FATAL-exits if unset). |
RELATA_TSA_URL | — | RFC 3161 Time-Stamping Authority endpoint used by CommitManifest::timestamp_head to anchor the manifest chain head to an independent, third-party-verifiable time source. Additive to, and independent of, KMS sign_head. Opt-in: unset means no timestamp anchor and every other manifest code path is unchanged — not a startup failure (crates/relata-prov/src/tsa.rs, HttpTsaClient::from_env). |
RELATA_REKOR_PUBLIC_KEY | — | PEM-encoded ECDSA P-256 public key trusted to verify a Sigstore Rekor transparency log's signed entry timestamp. Required only for a private/self-hosted Rekor mirror — without it, that verification has no trust root and fails closed. Not needed for the public Sigstore log, whose key is built in. |
Governance and privacy
| Variable | Default | Description |
|---|---|---|
RELATA_PURPOSE_MODE | open | Purpose-check enforcement: open (default — any non-empty purpose token is accepted and recorded for audit) | strict (only tokens pre-registered via RELATA_PURPOSES or the domain profile are accepted; others are rejected). Startup fails on any other value. |
RELATA_PURPOSES | — | Comma-separated allowed purpose strings for this deployment. |
RELATA_DOMAIN_PROFILE | enterprise | Domain preset that seeds default purposes and policies: enterprise | lea | finint | security | custom. Startup fails on any other value. |
RELATA_TENANCY_MODE | single | Canonical tenancy switch. single = single-tenant (default on every tier). multi is a cluster-only capability gated on the numeric max_tenants ceiling, not a license capability string — free/server FATAL unconditionally at startup (both are fixed at max_tenants=1); cluster with an effective max_tenants (license value, or the RELATA_MAX_TENANTS operator override) of 1 FATALs with guidance to raise the ceiling; cluster with max_tenants == 0 (unlimited) or > 1 is accepted and turns on strict isolation. Unattributed writes/reads return 400 MISSING_TENANT-equivalent (X-Organization-Id header is required …) in multi mode. Startup fails on unrecognised values. RELATA_ORG_MODERELATA_REQUIRE_ORG |
RELATA_TRUST_ORG_HEADER | true on free (no-auth only) | Whether to trust a client-supplied org header for tenant resolution. Unset: true on free without a bearer token configured (dev convenience); false when a token is set or on server/cluster. Set true explicitly to re-enable on a token-protected free deployment. |
RELATA_AUTH_MODE | bearer | Authentication mode: bearer | oidc | oidc-verify | saml | mtls. none is removed — startup FATAL if set. If unset and RELATA_BEARER_TOKEN is also unset, a random token is auto-generated and printed to stderr on first run. oidc is proxy-trust (an upstream gateway verifies the JWT and forwards X-Verified-Principal; requires RELATA_TRUST_UPSTREAM_PROXY=true). oidc-verify verifies the raw Authorization: Bearer <jwt> in-process (RS256/ES256 against the configured JWKS) — no upstream gateway required. |
RELATA_OIDC_ISSUER | — | Expected iss claim / issuer URL. Required for oidc and oidc-verify. |
RELATA_OIDC_JWKS_URI | — | JWKS URL used to fetch RS256/ES256 signing keys. In oidc-verify mode Relata fetches this itself (cached 5 min, 10 min grace window) and fails to start if the initial fetch fails. Required for oidc and oidc-verify. |
RELATA_OIDC_AUDIENCE | — | Expected aud claim value. Required for oidc and oidc-verify. |
RELATA_OIDC_CLIENT_ID | — | OAuth2 client id. Required for oidc (proxy-trust) only; not used by oidc-verify. |
RELATA_SAML_IDP_ENTITY_ID | — | SAML IdP entity id. Required for RELATA_AUTH_MODE=saml. |
RELATA_SAML_IDP_SSO_URL | — | SAML IdP single-sign-on URL. Required for saml. |
RELATA_SAML_SP_ENTITY_ID | — | SAML service-provider (Relata) entity id. Required for saml. |
RELATA_SAML_ACS_URL | — | SAML assertion-consumer-service URL. Required for saml. |
RELATA_AUDIT_REDACT_PII | — | Set true to redact sensitive field values from audit log entries. |
RELATA_AUDIT_FAIL_CLOSED | false | Opt-in: when true, a request whose audit entry could not be captured (bounded channel full AND the disk-backed spill also failed — a genuine drop, not the normal spill-absorbs-it case) is refused with 503 Service Unavailable instead of being served unaudited. Default false keeps the historical fail-open behaviour (the governed action still succeeds even if its audit record could not be captured). |
RELATA_CELL_POLICIES | — | Per-column cell-masking policies as a comma-separated list of Type.column=action entries, e.g. Person.ssn=mask,BankAccount.iban=tokenize,Customer.notes=allow. Actions: mask/redact (cell → [REDACTED], row kept), tokenize (deterministic surrogate — requires RELATA_TOKENIZE_KEY), allow (explicit no-op). A malformed entry refuses to start (fail-closed). Read at startup — restart required. See Access Control & Permissions. |
RELATA_TYPE_OWNERS | — | Not JSON — comma-separated Type:org pairs for read-side org-isolation (ADR-054), e.g. Alert:siem-lab,Alert:intops. A type can have more than one owner: list it more than once with a different org and both are granted independently, neither displacing the other — the repair path when a type's sole owner turns out wrong. Guard 6 falls back to the write-side ownership record (whichever org's X-Organization-Id first registered the type) when a type has no entry here at all. |
RELATA_PRIVACY_DP_EPSILON | — | Differential privacy epsilon (lower = more private, less accurate). |
RELATA_PRIVACY_MIN_GROUP | — | Minimum group size for DP aggregation suppression. |
RELATA_REGION | — | Deployment region tag (used for data-sovereignty routing and KMS). |
RELATA_ATTESTATION_PLATFORM | — | TEE attestation platform (nitro | sgx | sev). |
RELATA_TENANT_QUOTAS | — | Per-tenant cost-unit quota overrides. JSON object mapping tenant id → limit, e.g. {"org-7": 100000, "org-9": 5000}. Each configured tenant gets its own independent budget; unconfigured tenants fall through to the default limit. A malformed value is logged and ignored. |
RELATA_QUERY_QUOTA_WINDOW_SECS | — | Rolling-window length (seconds) for the per-principal read-cost quota. The quota now refills over this window instead of being a permanent cumulative cap that locks a principal out after 10k reads. |
RELATA_PHOTODNA_HAMMING | 10 | PhotoDNA/CSAM blocklist Hamming threshold for the ingest-side quarantine match. Default tolerates re-encode noise without over-flagging; lower = stricter. |
RELATA_NEAR_DUP_HAMMING | algo-keyed | Override the near-duplicate Hamming threshold. Unset keys off the algo tag (PDQ ≤ 31 / pHash ≤ 6). |
RELATA_CEDAR_POLICY_FILE | — | Path to a Cedar policy document installed at startup as a secondary access-control evaluation layer, applied after the built-in ABAC layer and only able to further restrict (deny-wins), never grant what ABAC denied. An unreadable file or invalid Cedar syntax refuses to start rather than running unrestricted. Unset: no Cedar layer, unchanged default behavior. |
RELATA_MAX_CROSS_ORG_JOINS | 1000 | Anti-aggregation guard: max cumulative cross-organization queries per principal before the planner blocks further cross-org queries from that principal. Only active in multi-tenant mode with type ownership configured. 0 disables the guard. |
RELATA_ORG_ROW_SCOPED_TYPES | — | Comma-separated additional type names exempted from the planner's fail-closed "no registered owner ⇒ deny" cross-org isolation default. Use only for a shared/connector-owned type every tenant writes its own rows into, where isolation is instead enforced by row-level tenant scoping. Do not use for a type meant to be genuinely single-organization-owned. |
RELATA_GDPR_DSAR_PAGE_LIMIT | 5000 | Per-page cap on records GET /gdpr/dsar materializes into a single response. A subject whose data spans more than this returns a cursor to fetch the next page — bounds memory risk for a single DSAR call without ever refusing to eventually return the complete export. |
RELATA_PACK_ALLOW_UNVERIFIED | false | Explicit, loud opt-in to install/run a content-pack binary with no matching signature sidecar (local/dev use only). Never bypasses an actual digest mismatch — only a missing sidecar. Every code path taken under this override prints a warning before proceeding. |
Backup
| Variable | Default | Description |
|---|---|---|
RELATA_BACKUP_DIR | — | Local directory for backup snapshots. |
RELATA_BACKUP_REPLICA_DIR | — | Secondary backup replica directory (off-host). |
RELATA_BACKUP_FULL_INTERVAL_SECS | — | Interval between full backups. |
RELATA_BACKUP_INCR_INTERVAL_SECS | — | Interval between incremental backups. |
RELATA_BACKUP_RETENTION_DAYS | — | Days to retain old backups before deletion. |
RELATA_BACKUP_TARGET | — | Default object-store target URL (s3://bucket/prefix) for scheduled backups when the --target CLI argument is not passed (crates/relata-cli/src/cmd_backup.rs). Unset = no default target; the caller must supply one. |
Streaming / Kafka
| Variable | Default | Description |
|---|---|---|
RELATA_KAFKA_BROKERS | — | Comma-separated Kafka broker addresses. |
RELATA_KAFKA_TOPIC | — | Kafka topic for ingest streaming. |
RELATA_KAFKA_GROUP_ID | — | Kafka consumer group ID. |
RELATA_KAFKA_ORGANIZATION | — | Tenant/agency tag applied to Kafka-ingested rows (mirrors the HTTP X-Organization-Id path). Unset/global = anonymous bucket. |
RELATA_KAFKA_PURPOSE | operations | Purpose token recorded in the audit entry for each Kafka-ingested row. |
RELATA_KAFKA_MAX_FRAME_BYTES | 67108864 (64 MiB) | Max byte size of a single Kafka fetch response frame. The default stays under the Kafka recv_response 128 MiB limit with framing overhead. Increase for high-throughput topics with large records; decrease on memory-constrained nodes. |
RELATA_KAFKA_PARTITIONS | 0 | Comma-separated list of partition indices to consume (e.g. 0,1,2,3). One independent supervised consumer task is spawned per partition. Unset/empty falls back to 0. |
RELATA_KAFKA_TLS_ENABLED | false | Wrap the Kafka wire-protocol connection in TLS. When true, RELATA_KAFKA_TLS_CA_CERT is required — there is no system-trust-store integration, so an unset CA with TLS enabled fails the connection closed rather than falling back to plaintext. |
RELATA_KAFKA_TLS_CA_CERT | — | Path to a PEM file with the CA certificate(s) used to verify the Kafka broker's TLS certificate. Required when RELATA_KAFKA_TLS_ENABLED=true. |
RELATA_KAFKA_SASL_MECHANISM | — | SASL mechanism: PLAIN, SCRAM-SHA-256, or SCRAM-SHA-512. Only PLAIN is currently implemented — the SCRAM mechanisms are recognized but fail the connection closed with an explicit "not yet implemented" error rather than connecting unauthenticated. Unset means no SASL authentication is attempted. |
RELATA_KAFKA_SASL_USERNAME | — | SASL/PLAIN username. Required when RELATA_KAFKA_SASL_MECHANISM=PLAIN. |
RELATA_KAFKA_SASL_PASSWORD | — | SASL/PLAIN password. Required when RELATA_KAFKA_SASL_MECHANISM=PLAIN. Never logged, including in trace instrumentation. |
Open Knowledge Framework (OKF)
| Variable | Default | Description |
|---|---|---|
RELATA_OKF_SEED | — | OKF seed file path for loading initial ontology entries. |
RELATA_OKF_SOURCE | — | OKF source identifier used in provenance tagging. |
RIFN feed broker
RIFN is Relata's intelligence feed network — a publisher/subscriber model for sharing threat-intel/OSINT-style content across deployments with tenant-aware access control.
| Variable | Default | Description |
|---|---|---|
RELATA_RIFN_BROKER_SEED | auto-generated per deployment, persisted under the data directory | Optional override: 32-byte hex Ed25519 signing seed for this broker. Set it to supply/rotate a seed explicitly, or to share one seed across cluster peers. A set-but-invalid value, or the public dev seed, is FATAL on server/cluster and a loud warning + dev-key fallback on free. |
RELATA_RIFN_LICENSE_KEYS | empty (deny-all) on server/cluster; dummy dev keys on free | Comma-separated subscriber license keys, each key[:tenant_id]. Each key's tier is derived from its prefix; unrecognized prefixes are skipped. Empty means a deny-all registry (fail-closed). The optional tenant binding decides which tenant-private entries the subscriber may read — never a client-supplied header. |
RELATA_RIFN_PUBLISHER | empty (deny-all) on server/cluster; dummy dev publisher on free | Semicolon-separated publisher records: DID, name, TLP sensitivity ceiling, verifying key, channel list, and an optional tenant binding. Malformed records are skipped with a warning. An empty verifying-key field means keyless trust-by-DID. |
Miscellaneous
| Variable | Default | Description |
|---|---|---|
RELATA_GRPC_STREAM_BATCH | — | Number of rows per gRPC streaming batch. |
RELATA_ORPHAN_SWEEP_SECS | 3600 | Interval for the background orphan-blob sweep. 0 disables the sweep. |
RELATA_BLOB_REFCOUNT_PERSIST_INTERVAL_MS | 1000 | Debounce interval for the blob-refcount snapshot. The decrement paths (decref / delete / sweep) write the snapshot at most once per this window instead of on every op, cutting a bulk erase/sweep from O(n) writes-per-op to O(1). Increments (put_blob) always persist synchronously and ignore this, so a still-referenced blob is never at risk. 0 disables debouncing (every decrement persists immediately — the legacy behaviour). A crash inside the window can only lose a decrement, leaving the on-disk refcount higher than reality (a leak the orphan sweeper reclaims), never lower. |
RELATA_OBJECT_PUT_TIMEOUT_SECS | 30 | Timeout for every remote object-store PUT (store/remote_io.rs:1108). Covers WAL segment flush, Parquet segment flush, manifest put, and blob put. Raise when running against a high-latency object store. |
RELATA_DEDUP_TOKEN_MIN_AGE_SECS | 86400 | Minimum age (seconds) before a dedup-token entry can be evicted by the TTL/LRU sweeper. Prevents replay-defence tokens from being reclaimed too soon (serve.rs:1702). |
RELATA_LOG_TARGETS | — | Per-module log-level override via EnvFilter directives, e.g. relata_storage=debug,relata_query=warn. Overrides RELATA_LOG_LEVEL for the named crates. |
RELATA_MAX_TENANTS | — | Manual override for the effective max_tenants ceiling — useful for testing with fewer tenants than the deployment is actually licensed for. Can only ever lower the effective ceiling below what the profile/license already permits (free/server fixed at 1; cluster at the verified license's max_tenants, or 1 with no license) — never raise it. A value above that ceiling (or 0/"unlimited" against a finite ceiling) is clamped down to the ceiling; only an unlimited (max_tenants: 0) license imposes no ceiling to clamp against. Unset = use the profile/license value unchanged. |
RELATA_FANOUT_MAX_OFFSET | 100000 | Largest OFFSET the cluster coordinator will inflate-and-slice for a fan-out query. Each shard is sent LIMIT offset+limit with OFFSET stripped; above this bound the query stays fail-closed (503) rather than pulling that many rows per shard across the network just to discard most of them. |
RELATA_FANOUT_PARALLEL_MERGE_THRESHOLD | 5000 | Row-count threshold above which the cluster coordinator's merge (GROUP BY re-grouping, global sort) switches to a rayon-parallel path. Also gated on rayon::current_num_threads() >= 4; below either gate the sequential path is used unchanged. |
RELATA_VENDOR_ROOT | ~/.relata-vendor/ | Root directory for the vendor-side License Manager's encrypted workspace (separate from the main server data directory). Set to place the workspace on a different volume. |
RELATA_VENDOR_PASSPHRASE | — | Passphrase for the License Manager's encrypted workspace. When unset, the tool prompts interactively — set it for automation/CI where no TTY is available. |
Deprecated / removed
| Variable | Status | Replacement |
|---|---|---|
RELATA_ALLOWED_ORIGINS | Removed — startup FATAL if set | Use RELATA_CORS_ALLOWED_ORIGINS |
RELATA_REQUIRE_MTLS | Removed — startup FATAL if set | Set RELATA_AUTH_MODE=mtls |
RELATA_MAX_CONNECTIONS | Removed — startup FATAL if set | Use RELATA_HTTP_MAX_CONNS. Previously silently stacked a second, lower-default ConcurrencyLimitLayer on top of RELATA_HTTP_MAX_CONNS's — not just an unused alias, an active double-limiter bug. |
RELATA_S3_BACKEND | Deprecated — presence-only check | Use AWS_ENDPOINT_URL or RELATA_OBJECT_STORE to configure the object store backend. Setting this variable only triggers a warning when RELATA_IN_MEMORY=true is also set. ⚠ still read at crates/relata-storage/src/remote.rs:236 — removal tracked separately. |
RELATA_STATUS_URL | Deprecated alias → RELATA_URL | ⚠ still read at crates/relata-cli/src/main.rs:2097, crates/relata-cli/src/main.rs:2212 — removal tracked separately. |
RELATA_ACCEL_ENDPOINT | Deprecated alias → RELATA_EMBED_URL | ⚠ still read at crates/relata-intelligence/src/accel.rs:361,476,598, crates/relata-cli/src/serve.rs:19790 (SSRF guard), crates/relata-cli/src/serve.rs:20587 — removal tracked separately. |
RELATA_SEARCH_SHORT_TERM_EXPANSION | Removed | Sub-3-char query terms now always fall back to prefix_search; the expansion is no longer env-gated. |
RELATA_SEARCH_SHORT_TERM_SCAN_CAP | Removed | The prefix-scan path has no configurable scan cap. |
RELATA_ALERT_MIN_SEVERITY | medium | Minimum severity for webhook alert delivery (low, medium, high, critical). Alerts below this are stored but not pushed. |
RELATA_ALERT_WEBHOOKS | — | Comma-separated webhook URLs for alert delivery (PagerDuty/Slack/email gateway). System-level fallback; tenant-specific rules via NotificationRule. |
RELATA_CLUSTER_ID | — | UUID identifying this cluster. Generated at cluster init; shared by all nodes. Used for license binding + cross-cluster protection. |
RELATA_CLUSTER_TIER | — | Cluster licensing tier: small, medium, large, enterprise. Sets max_nodes ceiling. |
RELATA_COLUMNAR_OVERRIDE | — | Force-enable or force-disable columnar analytical reads regardless of profile. true or false. |
RELATA_COORDINATOR_ADDR | — | Address of the cluster coordinator for auto-join. Set on reader/writer/indexer nodes. |
RELATA_MAX_NODES | — | Maximum nodes this cluster supports (from license). Nodes beyond this are rejected at gossip join. |
RELATA_CACHE_RAM_MB | Renamed | Use RELATA_STORE_MAX_RAM_MB (row-store RAM budget). |
RELATA_COORDINATOR | Output only | Printed by relata cluster-init; not read as input. Use RELATA_COORDINATOR_ADDR on peer nodes. |
RELATA_INGEST_QUEUE_CAPACITY | Renamed | Use RELATA_INGEST_QUEUE_MAX_BYTES. The old name appears in diagnostic JSON only and is not read from the environment. |
RELATA_NODE_ID | — | Override the persistent deployment UUID shown in the startup banner. Set this in Docker/container environments where $HOME is read-only and the file-backed UUID cannot be persisted. |