Skip to content

Configuration Reference

A node reads a single TOML file, config.toml, from its home directory (written by merod init and re-read on merod run). This page documents every section, key, type, default, and meaning, grounded in the structs the node actually deserializes.

These live at the root of the file, outside any section.

KeyTypeDefaultMeaning
mode"standard" | "readonly""standard"Node role. readonly disables JSON-RPC execution and is used for observer / TEE nodes. (The values serialize lowercase; the merod init --mode flag spells the read-only value read-only.)

The libp2p transport identity for the node. Generated automatically on merod init; you normally never hand-edit it.

KeyTypeDefaultMeaning
peer_idstring (base58)generatedLibp2p peer ID derived from the keypair. Must match keypair.
keypairstring (base58)generatedBase58-encoded protobuf libp2p keypair (the node’s private key).
[identity]
peer_id = "12D3KooWQrRJCnybfvLGZ7d4iaqGkGHpjLAB7PG6sFtXrHbkPMFc"
keypair = "23jhTbrf...redacted...CyLA"

libp2p listen addresses for peer-to-peer traffic.

KeyTypeDefaultMeaning
listenarray of multiaddr["/ip4/0.0.0.0/tcp/2428", "/ip4/0.0.0.0/udp/2428/quic-v1", "/ip6/::/tcp/2428", "/ip6/::/udp/2428/quic-v1"]Addresses the swarm binds for inbound peer connections. merod init seeds TCP and QUIC on both IPv4 (0.0.0.0) and IPv6 (::). Default port is 2428.

The local HTTP server: admin API, JSON-RPC, WebSocket, and SSE. Default port is 2528.

KeyTypeDefaultMeaning
listenarray of multiaddr["/ip4/127.0.0.1/tcp/2528", "/ip6/::1/tcp/2528"]Addresses the HTTP server binds. merod init seeds both IPv4 (127.0.0.1) and IPv6 (::1) loopback.
auth_mode"proxy" | "embedded""proxy"How auth is enforced. proxy expects an external auth proxy in front of the node; embedded runs the bundled auth service (see [server.embedded_auth]).
KeyTypeDefaultMeaning
enabledbooltrueEnables the admin API (and admin dashboard UI). When false, none of the admin routes are mounted.
KeyTypeDefaultMeaning
enabledbooltrueEnables the JSON-RPC endpoint at /jsonrpc.
KeyTypeDefaultMeaning
enabledbooltrueEnables the WebSocket endpoint at /ws.
ping_interval_secsinteger (seconds)30Interval between server-initiated pings. 0 disables server pings (rely on client pings).
pong_timeout_secsinteger (seconds)10If no pong arrives within this window after a ping, the connection is closed.
KeyTypeDefaultMeaning
enabledbooltrueEnables the Server-Sent Events endpoint at /sse.

Present only when auth_mode = "embedded". Carries the bundled auth service configuration (storage backend, etc.).

KeyTypeDefaultMeaning
nodesarray of multiaddr[]Bootstrap peers to dial on startup for initial network entry. merod init --network can seed this with IPFS or Calimero dev boot nodes.

Peer discovery and NAT-traversal behavior.

KeyTypeDefaultMeaning
mdnsbooltrueEnables local-network mDNS peer discovery.
advertise_addressboolfalseWhether to advertise external addresses to peers. Gates external_address.
external_addressarray of multiaddr[]Operator-supplied external addresses, seeded into the swarm’s confirmed external-address set (used for static-IP / hosted deployments instead of AutoNAT discovery).
KeyTypeDefaultMeaning
namespacestring"/calimero/devnet/global"Rendezvous namespace used for peer registration/discovery.
discovery_rpmfloat0.5Discovery queries per minute (throttle floor; 0.5 ≈ one query per 120s per peer in steady state).
discovery_intervalduration table{ secs = 15, nanos = 0 }Interval between rendezvous discovery ticks. Serialized as a nested [discovery.rendezvous.discovery_interval] table with secs / nanos.
registrations_limitinteger3Max rendezvous registrations to hold.
KeyTypeDefaultMeaning
registrations_limitinteger3Max relay reservations to hold.
KeyTypeDefaultMeaning
max_candidatesinteger5Max AutoNAT server candidates probed for external-address confirmation.
probe_intervalduration table{ secs = 10, nanos = 0 }Interval between AutoNAT probes. Serialized as a nested table with secs / nanos.

Settings for specialized (e.g. read-only / observer) nodes.

KeyTypeDefaultMeaning
invite_topicstring"mero_specialized_node_invites"Gossip topic used for specialized-node invite discovery.
accept_mock_teeboolfalseAccept mock TEE attestation. Testing only — never enable in production.

State-sync timing. Durations are expressed in milliseconds via the _ms suffixed keys.

KeyTypeDefaultMeaning
timeout_msinteger (ms)30000Per-request sync timeout.
session_deadline_msinteger (ms)30000 (falls back to timeout_ms)Outer deadline for one sync session run. Optional; lower it to fail-fast on stuck sessions when not doing cold-start snapshot syncs.
interval_msinteger (ms)5000Interval between sync attempts.
frequency_msinteger (ms)10000Sync scheduling frequency.
KeyTypeDefaultMeaning
pathpath"data"RocksDB datastore directory, relative to the node home.
KeyTypeDefaultMeaning
pathpath"blobs"On-disk blob storage directory, relative to the node home.

Context client configuration (the local signer used for group governance).

KeyTypeDefaultMeaning
migration_v2booltrueMaster switch for the hybrid zero-downtime migration framework. Pin false to restore the legacy namespace-cascade write-freeze.

The client signer config. The minimal form selects the local self-signer:

[context.config.signer.self]

Operator-tunable WASM VM limits. Every key is optional; an absent [runtime] section (or any absent sub-key) keeps the built-in default behavior.

KeyTypeDefaultMeaning
max_logsintegerbuilt-in VMLimits defaultMax log entries one execution may emit. Capped at 1_000_000; exceeding the limit traps the execution.
max_log_sizeinteger (bytes)built-in VMLimits defaultMax size of a single log line. Capped at 10 MiB; an over-long line traps the execution.

Bounds on-disk delta-log growth by pruning history older than a recent retain window. Enabled by default; set enabled = false to opt out.

KeyTypeDefaultMeaning
enabledbooltrueWhether periodic DAG compaction runs.
min_deltas_before_compactinteger10000Minimum delta rows a context must hold before it is eligible for compaction.
retain_recent_countinteger1000Number of most-recent deltas retained after a sweep. Must be strictly below min_deltas_before_compact.
check_intervalduration (seconds)3600Interval between compaction sweeps. Serialized as a plain integer count of seconds (e.g. check_interval = 3600), not a { secs, nanos } table. Must be non-zero.

The defaults keep ~1000 recent deltas per context and only start pruning once a context holds 10000 — fine for a quiet node, but a busy data-plane context can accumulate that history quickly. A production excerpt that prunes more aggressively on a high-write deployment:

[dag_compaction]
enabled = true
# Start pruning sooner on a high-write context...
min_deltas_before_compact = 4000
# ...but keep a generous recent window so peers can still catch up via deltas
# instead of falling back to a full snapshot.
retain_recent_count = 1500
# Sweep more often than the 1h default so growth is bounded between checks.
check_interval = 900

Keep retain_recent_count comfortably above the largest delta gap a lagging peer is expected to close incrementally: prune below that and the peer can only reconverge via a full snapshot. retain_recent_count must stay strictly below min_deltas_before_compact, and check_interval must be non-zero — the node refuses to start with [dag_compaction] enabled = true and either invariant violated, rather than silently letting the delta log grow unbounded.

Background tombstone GC (not configurable)

Section titled “Background tombstone GC (not configurable)”

DAG compaction is one of two independent background maintenance loops; the other is the tombstone garbage collector, and the two reclaim different things:

LoopReclaimsCadenceOperator-tunable?
DAG compactionold delta-log history older than the recent retain window[dag_compaction] check_interval (default 1h)Yes — the [dag_compaction] keys above.
Tombstone GCexpired CRDT tombstones (the markers a deleted entity leaves behind)fixed 12hNo — not a config.toml key.

When an entity is deleted, the CRDT layer keeps a tombstone so the deletion can win against a concurrent or out-of-order write that arrives later. A tombstone is retained for a fixed 24h before it becomes eligible for collection, and the GC loop runs every 12h, scanning each context and deleting tombstones older than that window. Both durations are compile-time constants, not config keys — there is no [gc] section and no gc_interval knob, so nothing here needs (or accepts) tuning. The retention window is deliberately longer than the GC interval, and shorter than the offline window that forces a full resync, so a node that reconnects within the window can still reconcile deletions incrementally.

Trusted Execution Environment configuration. The entire section is optional and absent on non-TEE deployments.

KeyTypeDefaultMeaning
urlURL— (required if present)URL of the Phala Cloud KMS service.
KeyTypeDefaultMeaning
ca_cert_pathpathunsetPEM CA certificate added to the KMS TLS trust store. Absolute path to an existing file.
client_cert_pathpathunsetPEM client certificate for mTLS. Must be set together with client_key_path.
client_key_pathpathunsetPEM client private key for mTLS. Must be set together with client_cert_path.

Policy for verifying KMS self-attestation before requesting storage keys.

KeyTypeDefaultMeaning
enabledboolfalseEnable KMS attestation verification before requesting keys.
accept_mockboolfalseAccept mock quotes (development only). Bypasses real attestation guarantees.
allowed_tcb_statusesarray of string["UpToDate"]Allowed TCB statuses for quote verification. Required non-empty when enabled and not accept_mock.
allowed_mrtdarray of string (hex)[]Allowed KMS MRTD measurement values. Required non-empty when enforcing real attestation.
allowed_rtmr0array of string (hex)[]Allowed KMS RTMR0 values. Required when enabled and not accept_mock.
allowed_rtmr1array of string (hex)[]Allowed KMS RTMR1 values. Required when enabled and not accept_mock.
allowed_rtmr2array of string (hex)[]Allowed KMS RTMR2 values. Required when enabled and not accept_mock.
allowed_rtmr3array of string (hex)[]Allowed KMS RTMR3 values. Required when enabled and not accept_mock.
binding_b64string (base64)unsetOptional 32-byte binding value for the /attest call. Defaults to the domain-separator binding.
policy_json_pathpathunsetPath to an externally-generated attestation policy JSON (for startup scripts that fetch/verify signed policy artifacts).

A complete, typical single-node config (chainless local self-signer):

mode = "standard"
[identity]
peer_id = "12D3KooWQrRJCnybfvLGZ7d4iaqGkGHpjLAB7PG6sFtXrHbkPMFc"
keypair = "23jhTbrf...redacted...CyLA"
[swarm]
listen = [
"/ip4/0.0.0.0/tcp/2428",
"/ip4/0.0.0.0/udp/2428/quic-v1",
"/ip6/::/tcp/2428",
"/ip6/::/udp/2428/quic-v1",
]
[server]
listen = ["/ip4/127.0.0.1/tcp/2528", "/ip6/::1/tcp/2528"]
auth_mode = "proxy"
[server.admin]
enabled = true
[server.jsonrpc]
enabled = true
[server.websocket]
enabled = true
ping_interval_secs = 30
pong_timeout_secs = 10
[server.sse]
enabled = true
[bootstrap]
nodes = []
[discovery]
mdns = true
advertise_address = false
[discovery.rendezvous]
namespace = "/calimero/devnet/global"
discovery_rpm = 0.5
registrations_limit = 3
[discovery.rendezvous.discovery_interval]
secs = 15
nanos = 0
[discovery.relay]
registrations_limit = 3
[discovery.autonat]
max_candidates = 5
[discovery.autonat.probe_interval]
secs = 10
nanos = 0
[sync]
timeout_ms = 30000
session_deadline_ms = 30000
interval_ms = 5000
frequency_ms = 10000
[datastore]
path = "data"
[blobstore]
path = "blobs"
[context]
migration_v2 = true
[context.config.signer.self]
[runtime.limits]
max_logs = 2048
max_log_size = 32768
[dag_compaction]
enabled = true
min_deltas_before_compact = 10000
retain_recent_count = 1000