Skip to main content

Configuration reference

Every server option is a command-line flag and an environment variable. The env var is the flag in upper snake case with a CELERIANT_ prefix: --data-root is CELERIANT_DATA_ROOT, --num-shards is CELERIANT_NUM_SHARDS. The server also loads a .env file from its working directory if one exists. At boot it logs every setting that differs from the default, so the log shows the effective config.

Switches such as --standalone take no value on the command line. Use the env form (CELERIANT_STANDALONE=true) to set them from a container spec.

Settings you cannot change later

The first boot writes server_meta.toml into --data-root. Every later boot compares the current settings with it and refuses to start on any mismatch. Changing one of these means a new data directory.

  • --num-shards
  • --routing-rule
  • --timestamp-precision
  • --timestamp-epoch-offset-secs
  • --reserve-coordinator-shard
  • --wal-compression-level
  • --wal-dictionary-name

--num-shards defaults to the CPU count of the machine it first ran on. Move that data directory to a host with a different core count and the node will not start. Set it explicitly.

Node and network

FlagDefaultNotes
--data-rootdataData directory. Must enforce O_DIRECT; the server checks at boot and exits if writes silently fall back to buffered I/O.
--listen-address0.0.0.0Bind address for the client and replication ports.
--client-port10000Client connections.
--replication-port10001Leader-to-follower replication and heartbeats.
--advertised-client-address{listen-address}:{client-port}Address written to S3 membership and returned in NotLeader errors. Set it when clients connect through a load balancer or proxy.
--advertised-replication-address{listen-address}:{replication-port}Replication address written to S3 membership. The peer dials this.
--standaloneoffSingle node. No replication, no S3 election.
--log-levelinfotrace, debug, info, warn, error. A RUST_LOG env var overrides it.

The advertised defaults inherit --listen-address. With the default 0.0.0.0, the peer and clients get an address they cannot dial, so a cluster node needs both advertised addresses set.

Sharding and data layout

All immutable after first boot.

FlagDefaultNotes
--num-shardsCPU countOne shard per core.
--routing-ruleaggregate_idorg_id, aggregate_type_id, or aggregate_id. Decides which aggregates share a shard and so which can be co-committed.
--reserve-coordinator-shardfalseShard 0 handles only cluster coordination (heartbeat, schema); client data routes to shards 1 and up. Needs at least 2 shards.
--timestamp-precisionmillisecondsPrecision of the server-assigned timestamp: milliseconds, microseconds, or nanoseconds.
--timestamp-epoch-offset-secs0Custom epoch, as seconds from the Unix epoch. Shifts the server-assigned timestamp, not event timestamps a client sets.
--wal-compression-level3zstd level for the WAL.
--wal-dictionary-namejson-web-events-v1Name of the zstd dictionary, not a path. The built-in one is written to dictionary.zstd_dict on first boot.

Cluster and failover

FlagDefaultNotes
--heartbeat-interval-ms500Leader heartbeat cadence.
--heartbeat-timeout-ms= intervalTimeout for one heartbeat connect and request. Keep it below --heartbeat-lease-duration-ms.
--heartbeat-hard-timeout-multiplier4Hard cap on a heartbeat, as a multiple of the timeout. Catches kTLS sends blocked in the kernel that ignore the soft timeout.
--heartbeat-lease-duration-ms1500Silence after which the follower treats the leader's lease as expired and challenges.
--heartbeat-starve-threshold-ms500While a heartbeat has been in flight longer than this, reject writes (FollowerHeartbeatStarved) so the NIC has room for the ack. Skipped when the follower is unreachable. 0 disables.
--s3-lease-duration-ms30000TTL of the lease object in S3, independent of heartbeat timing. See leader election.
--max-clock-drift-ms500Drift allowance added to lease checks. The leader fences itself this much before expiry.
--internode-connection-timeout-ms1000Inter-node TCP connect timeout.
--internode-request-timeout-ms2000Bounds one inter-node round trip. Raise it on high-latency links.
--internode-max-request-size64 MiBCap on one replication batch. In-flight write bytes reaching it trigger write backpressure.

Write pipeline

Wider windows batch more writes per fsync or send. That buys throughput and costs per-write latency.

FlagDefaultNotes
--fsync-delay-us4000Window in which writes are coalesced into one fsync.
--replication-delay-us17000Same, for the replication send to the follower.
--s3-replication-delay-us500000Same, while replicating through S3 fallback. Longer, to put more entries in each upload.
--replication-rollback-cooldown-us500000After a replication rollback, reject writes with ReplicationBackpressure for this long so the queue drains.
--s3-max-concurrent-fallback-uploads128Parallel S3 fallback uploads across all shards. Sized for AWS; lower it for MinIO or a LAN store where saturation can starve lease renewal.

S3

Required unless --standalone. A clustered node without S3 retries its membership registration every 2 s and never finishes booting.

FlagDefaultNotes
--s3-enabledoffTurns S3 on. Needs --s3-region and --s3-bucket.
--s3-region / --s3-bucketnoneThe store must support conditional writes (If-Match / If-None-Match); election depends on them.
--s3-access-key-id / --s3-secret-access-keynoneStatic credentials. Leave both unset to use the EC2 instance profile. The standard AWS_* env vars are not read.
--s3-subfoldernoneOne-level prefix, so several clusters can share a bucket.
--s3-endpoint-overridenoneFor MinIO and other S3-compatible stores.
--s3-retry-max-duration-secsunsetCaps how long a lease or election call retries an unreachable S3 (backoff from 1 s, doubling to 30 s). Unset retries forever.
--s3-allow-http / --s3-skip-signatureoffLocal testing only.

The server checks S3 reachability at boot and exits if the endpoint, credentials, or bucket are wrong.

TLS and authentication

FlagDefaultNotes
--tls-modedisableddisabled (plaintext only) or strict (TLS only). Needs kernel kTLS. See TLS and mTLS.
--tls-ca-cert / --tls-node-cert / --tls-node-keynoneTrust root and node identity, PEM. All three required under strict.
--tls-intracluster-ca-certnoneSeparate CA for the replication port. When set, the client port trusts only --tls-ca-cert.
--tls-client-cert / --tls-client-keynoneCertificate the client port presents instead of the node cert.
--tls-client-authrequirerequire (mTLS), optional, or none.
--tls-cert-reload-interval-secs0How often to re-read cert files and hot-reload them. 0 disables.
--require-client-identityoffClients must send the identity handshake first.
--insecure-allow-plaintext-authoffAllow API keys or client identity without TLS. Development only.

API keys are not a flag. The server reads them from <data-root>/api_keys.toml; celeriant keys generate --data-root <dir> creates it. If API keys or --require-client-identity are on and TLS is off, the server refuses to start unless --insecure-allow-plaintext-auth is set.

Storage, compaction, and memory

FlagDefaultNotes
--shard-log-preallocate-bytes1 GiBSize of each WAL file.
--compaction-check-interval-secs7200How often to scan for compactable segments.
--compaction-min-reclaimable-ratio0.20Share of reclaimable bytes a segment needs before it is compacted.
--compaction-temp-dir{shard_dir}/.compaction_tmp/Must be on the same filesystem as --data-root. Checked at boot.
--cache-warmup-max-secsunsetTime limit for cache warmup on shard open. Unset means no limit.
--memory-consumption-percent80Share of detected memory (the cgroup limit if lower) given to caches. 1 to 95.
--memory-budget-bytesunsetExplicit total cache budget. Overrides detection.
--recent-write-cache-ratio0.73Share of each shard's budget for the recent-write cache.
--negative-lookup-cache-bytes2 MiBPer-shard budget for the idempotency-scan blooms. Eviction costs a rebuild scan, never correctness.

Request limits

FlagDefaultNotes
--max-request-size16 MiBPer client request, compressed and uncompressed.
--max-response-size64 MiBPer response.
--max-requested-latency-ms2000Upper bound on the latency a watch may request.
--max-watch-subscribers16384Watch subscriptions per shard. Past it, a watch gets error 8005.
--max-schema-size-bytes16384One schema definition.
--list-page-size2000Entities per list page.
--list-max-duration-ms2000Time a list may spend scanning the WAL.
--list-max-concurrent16Concurrent list operations per shard.
--read-max-concurrent64Concurrent backward metablock scans per shard.
--client-connection-timeout-ms30000How long a client has to read server messages before it is dropped.
--handshake-concurrency8TLS handshakes in flight per shard, per port.

Observability

FlagDefaultNotes
--metrics-enabledonServes /metrics and /health. The flag cannot switch it off; set CELERIANT_METRICS_ENABLED=false.
--metrics-port9090See Monitoring.

Low-level tuning

Leave these alone unless a profile says otherwise.

FlagDefaultNotes
--mesh-channel-size8192Inter-shard channel capacity.
--max-open-files1000Open files per shard.
--read-max-chunk-size / --write-max-chunk-size32768Disk read and write chunk size in bytes.
--chain-read-window-bytes1024Per-hop read window when walking an aggregate's backlink chain for old versions. Raise toward the read chunk size for shards with few, long aggregates.
--preempt-timer-us250How long a task runs before the scheduler and reactor get the CPU. 50 to 100000.
--wal-join-data-meta-writestrueSubmit a sync's datablock and metablock writes together. Takes an explicit true or false.

Tuning notes

  • S3 fallback costs latency. While the follower is unreachable, writes replicate through S3 and wait on --s3-replication-delay-us (500 ms by default) to fill each upload. Fewer PUTs, slower acks. A follower down for hours means hours of that.
  • NTP is required. The server warns at boot if the kernel clock is not NTP-disciplined. --max-clock-drift-ms is slack for lease checks, not a substitute for sync.