Configuration
RelataDB is configured through environment variables, with an optional relata.toml config file for persisted settings (search order: --config <path> flag, RELATA_CONFIG env var, ./relata.toml, then ~/.relata/config.toml). A bare relata serve starts in dev mode with safe defaults. Production requires three things: a profile, a bearer token, and (optionally) an object-store endpoint.
Strict parsing. Every
RELATA_*value is validated at startup. A malformed value (e.g.RELATA_PORT=abcorRELATA_WAL_SYNC=true) causes a FATAL startup error — Relata refuses to boot rather than silently using a wrong default. Removed/renamed vars (e.g.RELATA_ORG_MODE) also FATAL.Operator tools:
relata config --print-template— emit a commented.envtemplate of everyRELATA_*var.relata config --validate— check your config before boot.relata config --migrate— auto-rewrite old var names to the current surface (run when upgrading from 1.x).relata doctor— 12 pre-flight checks (config, ports, KMS, disk).
Pick a profile first
RELATA_PROFILE is the master switch. Set it before anything else.
# Local dev — no auth required, unbounded RAM, eager restart
RELATA_PROFILE=free relata serve
# Single-node production — 1 GB row-store RAM wall, disk-first walls on, requires bearer token
RELATA_PROFILE=server RELATA_BEARER_TOKEN=<your-strong-token> relata serve
# Multi-node (alpha) — same as server plus coordination
RELATA_PROFILE=cluster RELATA_BEARER_TOKEN=<your-strong-token> relata servelite was a legacy alias for free and is now rejected outright — startup fails if RELATA_PROFILE=lite is set; use free. The server and cluster profiles refuse to start without RELATA_BEARER_TOKEN set.
| Profile | RAM wall | Lazy restart | Disk-first walls |
|---|---|---|---|
free | unbounded | off | off |
server | 1024 MB | on | on |
cluster | 1024 MB | on | on |
Domain profile
RELATA_DOMAIN_PROFILE loads the matching ontology overlay and default detector packs.
RELATA_DOMAIN_PROFILE=finint relata serve| Value | Use case | Default detectors |
|---|---|---|
enterprise (default) | General business | network,contact,crypto |
lea | Law enforcement | network + identity |
finint | Financial intelligence | network + contact + crypto |
security | Security operations | network + device + crypto |
custom | Bring-your-own ontology | whatever you wire |
Environment variable reference
Profile and deployment
| Variable | Default | Description |
|---|---|---|
RELATA_PROFILE | free | Deployment shape: free | server | cluster. lite is removed — rejected at startup. |
RELATA_DOMAIN_PROFILE | enterprise | Ontology overlay: enterprise | lea | finint | security | custom. |
RELATA_PORT | 9090 | HTTP/gRPC listen port. |
Auth
| Variable | Default | Description |
|---|---|---|
RELATA_BEARER_TOKEN | — | Unset = dev mode, no auth, pgwire disabled. Required on server/cluster. |
RELATA_ADMIN_TOKEN | — | Secondary token for /admin/* operations. |
RELATA_AUTH_MODE | — | oidc | oidc-verify | saml | mtls for federated auth. |
RELATA_PLAINTEXT_OK | — | true to allow plain HTTP on server/cluster (not recommended). |
Storage
| Variable | Default | Description |
|---|---|---|
RELATA_DATA_DIR | ./data/relata | Root for WAL state and local object store. |
RELATA_LOCAL_DATA_DIR | — | Explicit local object-store path (dedicated volume). |
AWS_ENDPOINT_URL | — | S3-compatible endpoint. When set, overrides local disk. Also set AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, RELATA_S3_BUCKET. |
RELATA_IN_MEMORY | — | true = in-memory only, data lost on restart. |
RELATA_WAL_SYNC | interval | Process-global WAL fsync mode: always (fsync on every flush, RPO≈0) | interval (default — batched fsync every ~10 ms, RPO≈10 ms) | off (page-cache only). Any other value (including true/1) is a FATAL startup error. |
RAM and cache limits
| Variable | Default (server/cluster) | Description |
|---|---|---|
RELATA_STORE_MAX_RAM_MB | 1024 | Row-store RAM budget before spill to disk. Unbounded on free. |
RELATA_DISKANN_MAX_RESIDENT | 0 (unbounded) | Soft cap on RAM-resident vectors. |
RELATA_MV_MAX_ROWS | 1000000 | Max rows in an incremental materialized-view cache. 0 = unbounded. |
RELATA_VECTOR_COLD_RESIDENT_MAX | 100000 | Max staging vectors in an IVF cold bucket before spill. |
RELATA_TOMBSTONE_CACHE_MAX_ROWS | 1024 | Per-type tombstone cache size. Lower saves RAM; raises on-disk re-reads. |
RELATA_DECODED_SEGMENT_CACHE_MAX | 64 | Max decoded disk-segment entries in RAM. |
Cold-start and restart
| Variable | Default | Description |
|---|---|---|
RELATA_LAZY_RESTART | false (true on server/cluster) | true loads manifest catalog only — O(manifest) not O(rows). |
RELATA_HYDRATE_RECENT_SEGMENTS | 0 | With lazy restart, pre-warm the newest N segments into RAM. 0 = fully lazy. |
RELATA_FLUSH_SEGMENT_MAX_ROWS | 250000 | Max rows per flushed Parquet segment. Larger deltas split into ceil(delta/N) segments. |
Search and embedding
| Variable | Default | Description |
|---|---|---|
RELATA_SEARCH_PRESET | balanced | BM25/FTS fuzzy expansion: strict | balanced | lenient. |
RELATA_EMBED_BATCH_SIZE | 32 | Texts per embed() call per drain cycle. Higher = fewer round-trips, more first-result latency. |
RELATA_EMBED_CONCURRENCY | 4 | Concurrent drain-worker tasks. |
RELATA_EMBED_QUEUE_MAX | 100000 | Hard cap on embedding backlog. |
RELATA_EMBED_TIMEOUT_MS | 30000 | Timeout for embedder sidecar HTTP calls. |
RELATA_EMBED_CIRCUIT_COOLDOWN_MS | 60000 | After 5 consecutive errors, circuit opens; /health/ready returns 503. |
RELATA_DETECT_BATCH_SIZE | 256 | Chunk size for batched identity detection. |
SmartIngest detector packs
# Default
RELATA_DETECT_PACKS=network,contact,crypto
# Add financial and payment
RELATA_DETECT_PACKS=network,contact,crypto,financial,payment
# All packs
RELATA_DETECT_PACKS=all
# Disable detection
RELATA_DETECT_PACKS=noneAvailable opt-in additions: financial, payment, social, transport, device, ics.
Observability
| Variable | Default | Description |
|---|---|---|
RELATA_LOG_FORMAT | pretty | pretty for terminals, json for log shippers. |
RELATA_LOG_LEVEL | info | trace | debug | info | warn | error. |
RELATA_OTLP_ENDPOINT | — | OTLP/HTTP trace exporter, e.g. http://otel-collector:4318/v1/traces. Unset = OTel fully disabled. |
RELATA_OTLP_SAMPLE_RATIO | 0.01 | TraceID-ratio sampler. 1.0 = sample everything. |
RELATA_METRICS_PUBLIC | — | true serves /metrics without a bearer token (for Prometheus scrapers behind mTLS/NetworkPolicy). |
Rate limits
| Variable | Default | Description |
|---|---|---|
RELATA_RATE_LIMIT_RPS | profile-dependent | Per-principal requests/sec cap. |
RELATA_RATE_LIMIT_AUTH_FAIL_RPS | profile-dependent | Auth-failure rate cap. 0 is treated as 1. Use 99999 to disable. |
To disable rate limits for load tests or air-gapped demos:
RELATA_RATE_LIMIT_RPS=99999 RELATA_RATE_LIMIT_AUTH_FAIL_RPS=99999 relata servePurpose enforcement
| Variable | Default | Description |
|---|---|---|
RELATA_PURPOSE_MODE | open | strict = only registered purposes accepted; open = any non-empty string. |
RELATA_PURPOSES | — | Comma-separated registered purpose IDs, e.g. analytics,audit,compliance. |
Minimal production docker-compose
Copy this, replace the token and bucket values, and run docker compose up -d.
services:
relata:
image: ghcr.io/relatadb/relata:latest
restart: unless-stopped
ports:
- "9090:9090"
environment:
RELATA_PROFILE: server
RELATA_BEARER_TOKEN: "change-me-use-openssl-rand-hex-32"
RELATA_PORT: "9090"
RELATA_DOMAIN_PROFILE: enterprise
RELATA_PURPOSE_MODE: strict
RELATA_PURPOSES: analytics,audit,compliance
RELATA_STORE_MAX_RAM_MB: "2048"
RELATA_LAZY_RESTART: "true"
RELATA_HYDRATE_RECENT_SEGMENTS: "5"
RELATA_LOG_FORMAT: json
RELATA_LOG_LEVEL: info
RELATA_OTLP_ENDPOINT: "http://otel-collector:4318/v1/traces"
RELATA_METRICS_PUBLIC: "true"
AWS_ENDPOINT_URL: "http://minio:9000"
AWS_ACCESS_KEY_ID: minio
AWS_SECRET_ACCESS_KEY: minio123
RELATA_S3_BUCKET: relata-data
volumes:
- relata-data:/var/lib/relata
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9090/health"]
interval: 10s
timeout: 5s
retries: 3
depends_on:
minio:
condition: service_healthy
minio:
image: minio/minio:latest
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: minio
MINIO_ROOT_PASSWORD: minio123
ports:
- "9000:9000"
- "9001:9001"
volumes:
- minio-data:/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 10s
timeout: 5s
retries: 3
volumes:
relata-data:
minio-data:Verify the node is healthy after startup:
curl http://localhost:9090/health
curl http://localhost:9090/health/ready
curl http://localhost:9090/versionSingleton enforcement
relata serve acquires an exclusive flock on data_dir/relata.lock. If two pods share the same PVC, the second one fails with a clear error rather than silently splitting writes. This is especially important in Kubernetes rolling updates — use RollingUpdate strategy with maxUnavailable: 1 or switch to a StatefulSet.
See also
- Auth & Security — bearer tokens, OIDC, mTLS, ACL
- Backup & Restore — WAL, Parquet, MinIO setup
- Scaling — RAM walls, paged backends, lazy restart
- Observability — logs, metrics, traces, health probes