Deployment
Relata ships three deployment profiles from one binary. The SDK works identically across all three; only the runtime characteristics differ.
| Profile | Use case | Default caps | Start command |
|---|---|---|---|
lite | Embedded / single-process / dev / CI | Unbounded (small datasets stay in RAM) | RELATA_PROFILE=lite relata serve |
server | Single-node production | RAM walls default-on at 1024 MB | RELATA_PROFILE=server relata serve |
cluster | Multi-node distributed (alpha) | Same as server, plus cluster coordination | RELATA_PROFILE=cluster relata serve |
lite is the default.
Profile defaults that bite
The server and cluster profiles enable the disk-first walls by default so you don’t OOM in production:
RELATA_STORE_MAX_RAM_MB→ 1024 MB on server/cluster (unbounded on lite)- Graph
RELATA_GRAPH_RAM_BUDGET_MB→ 1024 MB - Identity
RELATA_IDENTITY_RAM_BUDGET_MB→ 1024 MB - DiskANN
RELATA_DISKANN_MAX_RESIDENT→ 1,000,000 resident/bucket
An explicit env var always overrides the profile default. The budgets are generous — small/medium deployments stay fully resident (no behaviour change).
Lite — local dev
relata serveStorage defaults to local disk at ./data/relata/objects (persistent, no config needed). Override with RELATA_LOCAL_DATA_DIR for a custom path, or AWS_ENDPOINT_URL for S3/MinIO.
Without RELATA_BEARER_TOKEN the server runs in dev mode (no auth, pgwire disabled). The warning is expected:
WARNING: RELATA_BEARER_TOKEN not set — running in unauthenticated mode (dev only)For air-gapped / demo / testing (disables rate limits):
RELATA_AIRGAP=true relata serveServer — single-node production
RELATA_PROFILE=server \
RELATA_BEARER_TOKEN=change-me \
RELATA_PORT=9090 \
relata serveSet RELATA_PLAINTEXT_OK=true only if you terminate TLS at a reverse proxy / sidecar.
Object-store persistence
Object-store persistence is always on — Relata defaults to local disk at RELATA_DATA_DIR/objects. RELATA_LOCAL_DATA_DIR overrides the path; AWS_ENDPOINT_URL selects S3 / MinIO / R2 / GCS / Azure Blob. WAL + Parquet snapshots persist across restarts.
Cold-restart RTO (measured at 10 M rows)
| Phase | Time |
|---|---|
| WAL + Parquet flush (shutdown) | ~15 s |
| Cold-load from Parquet (restart, no warm cache) | ~55 s |
Single-node RTO ≈ 1 minute at 10M-row scale. Paged backends + WAL replay are the production path for faster restarts on larger datasets.
For faster cold-load:
RELATA_LAZY_RESTART=true \
RELATA_HYDRATE_RECENT_SEGMENTS=5 \
relata serveLazy restart loads the manifest catalog only (O(manifest), not O(rows)); the newest N segments hydrate into RAM at startup and the rest hydrate on demand.
Cluster — multi-node (alpha)
RELATA_PROFILE=cluster \
RELATA_NODE_ID=node-1 \
RELATA_ROLE=coordinator \
RELATA_PEERS=http://node-2:9090,http://node-3:9090 \
relata serve| Role | Responsibility |
|---|---|
coordinator | Query planning, request routing |
reader | Read-only query execution |
writer | Write ingest + WAL |
indexer | Background indexing (FTS, vectors, identity) |
Cluster is alpha — petabyte / 200B-subscriber cardinality still needs sharding / cluster fan-out (epic #797).
Observability
| Variable | Default | Effect |
|---|---|---|
RELATA_LOG_FORMAT | pretty | json for production log shippers. |
RELATA_LOG_LEVEL | info | Log level. |
RELATA_OTLP_ENDPOINT | — | OTLP/HTTP traces endpoint. Unset = OpenTelemetry fully disabled. |
RELATA_OTLP_SAMPLE_RATIO | 0.01 | Parent-based TraceID-ratio sampler. |
RELATA_METRICS_PUBLIC | — | Serve /metrics without a bearer token (Prometheus behind network-layer auth). |
Graceful shutdown
The server handles SIGTERM gracefully:
- Stops accepting new requests.
- Drains in-flight queries (configurable drain timeout).
- Flushes the WAL + Parquet snapshot.
- Closes the HTTP/gRPC listeners.
Cold-restart RTO at 10M rows is ~1 minute (see above).
See also
- Environment Variables — full reference
- Limits & Caveats — capacity & scaling
- Protocol Compatibility — bring-your-own-client