Store-and-forward configuration
This page is the configuration reference for the SF connect-string keys. For the model behind each knob, read Concepts; for operational guidance read Operating and tuning.
Shared keys (authentication, TLS, address list) are documented on the connect-string reference. The keys below are the SF-specific subset.
Storage keys
These keys select between memory mode and SF mode and govern on-disk
layout. The single switch is sf_dir: unset → memory mode, set → SF
mode.
| Key | Type | Default | Description |
|---|---|---|---|
sf_dir | path | unset | Group root directory. When set, the slot lives at <sf_dir>/<sender_id>/ and unacked data is durable across process restarts. When unset, the substrate runs in memory mode. |
sender_id | string | default | Slot subdirectory name. Two senders sharing the same sender_id and sf_dir will collide on the slot lock. Must not contain path separators or be empty. |
sf_max_segment_bytes | size | 4M | Per-segment file size; rotation threshold. |
sf_max_total_bytes | size | 128M (memory) / 10G (SF) | Hard cap on resident SF storage. Triggers producer backpressure when full. |
sf_durability | enum | memory | memory (page-cache durable) and periodic (background checkpoint to stable storage) both ship. periodic requires sf_dir. flush and append parse but are rejected at build time, except in the Node.js client, which accepts append, making every frame durable before its append completes, and rejects flush when parsing. The .NET client accepts memory only. |
sf_sync_interval_millis | int (ms) | 5000 | Checkpoint cadence for sf_durability=periodic; rejected without it. A floor, not a guarantee: scheduler and storage latency add to it. |
sf_append_deadline_millis | int (ms) | 30000 | How long a producer appendBlocking call waits for ACK-driven trim to free space before throwing. |
drain_orphans | bool | off | Scan <sf_dir>/* at startup and spawn drainers for sibling slots that contain unacked data. See orphan adoption. |
max_background_drainers | int | 4 | Cap on concurrent orphan drainers. |
Size values accept integer bytes or unit suffixes (K, M, G, T)
using binary multipliers.
These keys are also documented on the central connect-string reference.
Reconnect keys
Govern the in-flight reconnect loop after the wire breaks. Backoff math and host-walk semantics are documented in Client failover concepts.
| Key | Type | Default | Description |
|---|---|---|---|
reconnect_max_duration_millis | int (ms) | 300000 (5 min) | Bounds the blocking sync initial connect only (initial_connect_retry=on/sync). A running sender's reconnect loop never consults it and retries indefinitely. |
reconnect_initial_backoff_millis | int (ms) | 100 | Initial backoff sleep at round exhaustion. |
reconnect_max_backoff_millis | int (ms) | 5000 | Cap on the exponential backoff. With equal-jitter the actual sleep lands in [max, 2·max). |
initial_connect_retry | enum | off | off (alias false): first-connect failure is terminal. on (aliases sync, true): same retry loop as reconnect, blocking the constructor. async: same retry loop in the I/O thread, non-blocking. |
close_flush_timeout_millis | int (ms) | 60000 on Java and .NET; 5000 on Rust, C, C++, Python, and Node.js | close() blocks up to this long waiting for ackedFsn ≥ publishedFsn. 0 or -1 skips the drain wait. The safety-net checkError() still runs. |
Cross-reference: connect-string #reconnect-keys.
Durable-ack keys
Opt in to object-store-durable trim. See Durable-ack: when to opt in.
| Key | Type | Default | Description |
|---|---|---|---|
request_durable_ack | bool | off | Opt-in via the upgrade header X-QWP-Request-Durable-Ack: true. Trim is then driven by STATUS_DURABLE_ACK frames only; OK frames no longer advance the trim watermark. Connect fails loudly if the server does not echo X-QWP-Durable-Ack: enabled. WebSocket transports only. |
durable_ack_keepalive_interval_millis | int (ms) | 200 | Cadence of WebSocket PING the I/O loop sends while there are pending durable confirmations and the producer is idle. 0 or negative disables. |
Error-handling keys
| Key | Type | Default | Description |
|---|---|---|---|
error_inbox_capacity | int (≥16) | 256 | Bounded SPSC queue capacity for async error notifications. Overflow drops the oldest entry and increments getDroppedErrorNotifications. |
on_server_error, on_schema_error, on_parse_error, on_internal_error, on_security_error, on_write_error | enum | per category | Override the default policy (HALT or DROP_AND_CONTINUE) for a category. Reserved in the spec but not yet recognised by the connect-string parser. |
The per-category defaults are documented in
Concepts § Error frames.
PROTOCOL_VIOLATION and UNKNOWN are forced HALT and not user-overridable.
Other relevant keys
These keys are not SF-specific but affect SF behaviour. See the connect-string reference for the canonical entries.
| Key | Type | Default | Description |
|---|---|---|---|
addr | host[:port][,host[:port]…] | required | Multi-host failover list. See Client failover configuration. |
username / password | string | unset | HTTP Basic auth on the upgrade request. |
token | string | unset | Bearer token on the upgrade request. |
tls_verify | enum | on | on or unsafe_off. Applies to wss:: / TLS connections. |
tls_roots | path | system trust | Custom CA trust store. |
tls_roots_password | string | unset | Trust store password. |
auto_flush | bool | on | Global on/off for auto-flush triggers. |
auto_flush_rows | int / off | 1000 | Row-count flush trigger. |
auto_flush_bytes | int / off | 0 (off) | Byte-size flush trigger. |
auto_flush_interval | int (ms) / off | 100 | Time-since-first-row flush trigger. |
init_buf_size | size | 64K | Initial encode buffer capacity. |
max_buf_size | size | 100M | Max encode buffer capacity. |
max_name_len | int | 127 | Local validation cap for table / column names. |
Validation
The parser rejects:
- Unknown keys (forward compatibility is via the spec, not silent acceptance).
sf_durabilityvalues other thanmemory,periodic,flush, andappend.flushandappendparse but are rejected at build time today, except that the Node.js client acceptsappendand rejectsflushwhen parsing.sender_idcontaining path separators or empty.request_durable_ack=onon non-WebSocket transports.
Worked examples
Single-node memory-mode producer
try (Sender sender = Sender.fromConfig("ws::addr=localhost:9000;")) {
sender.table("events")
.stringColumn("source", "edge-42")
.longColumn("count", 1)
.atNow();
}
No sf_dir, so memory mode. The default 128 MiB cap absorbs short
network blips. A sender crash loses the unacked tail.
Single-node durable producer
try (Sender sender = Sender.fromConfig(
"ws::addr=localhost:9000;sf_dir=/var/lib/qdb-sender;")) {
// ...
}
Same producer code; SF mode is enabled by the one extra key. Unacked
data persists at /var/lib/qdb-sender/default/ across crashes.
Multi-host with object-store durability
try (Sender sender = Sender.fromConfig(
"wss::addr=node-a:9000,node-b:9000,node-c:9000;"
+ "sf_dir=/var/lib/qdb-sender;sender_id=ingest-svc;"
+ "request_durable_ack=on;"
+ "username=ingest;password=…;")) {
// ...
}
wss:: for TLS, three-host failover, durable-ack opt-in. Slot lives at
/var/lib/qdb-sender/ingest-svc/. The connect fails loudly if any peer
returns an upgrade without X-QWP-Durable-Ack: enabled.
Multi-tenant host with orphan rescue
try (Sender sender = Sender.fromConfig(
"wss::addr=node-a:9000;sf_dir=/var/lib/qdb-sender;"
+ "sender_id=worker-" + workerInstanceId + ";"
+ "drain_orphans=on;max_background_drainers=8;")) {
// ...
}
Each worker instance has a unique sender_id. When a worker crashes and
a new instance comes up under a different sender_id, the new
instance's foreground sender adopts the dead worker's slot in the
background and drains it.
Long-outage tolerance for unattended ingest
try (Sender sender = Sender.fromConfig(
"wss::addr=primary:9000;sf_dir=/var/lib/qdb-sender;"
+ "sf_max_total_bytes=50G;"
+ "reconnect_max_duration_millis=3600000;"
+ "initial_connect_retry=async;")) {
// ...
}
50 GB of buffer space, a one-hour reconnect budget, async initial connect so the constructor returns immediately even if the server is down. Suitable for edge / IoT producers on unreliable links.
Where each key is documented
| Group | Connect-string reference |
|---|---|
Storage (sf_dir, sender_id, …) | #sf-keys |
Reconnect (reconnect_*, initial_connect_retry, close_flush_timeout_millis) | #reconnect-keys |
Failover (addr, zone, target, auth_timeout_ms) | #failover-keys |
Auth (username, password, token) | #auth |
TLS (tls_*) | #tls |