Server configuration

v3.0.0

Every kds_server config key with its default and meaning, the command-line flags, and how settings are resolved.

In this article

kds_server reads its settings from built-in defaults, then a config file, then command-line flags. A later source wins. The config file is plain key = value lines. buffer_pool_frames has no default and must be set, so in practice every server needs a config file. kds.conf.sample in the source tree is a commented template.

How settings are resolved

  1. Built-in defaults.
  2. The config file, passed with --config <path>.
  3. Command-line flags. A flag always wins over the file, wherever --config appears on the command line.

File format

  • One key = value per line. # starts a comment.
  • Quote a value to keep surrounding whitespace or a literal #.
  • Boolean keys take on/off, true/false, yes/no or 1/0.
  • Every key is optional except buffer_pool_frames.

Errors stop the server

The server refuses to start, naming the file and line, on any of these:

  • An unknown key. A typo such as chekpoint_interval_ms would otherwise look like it worked.
  • A duplicate key, a malformed line, or an out-of-range value.
  • A retired key (see Retired keys).

Storage

KeyDefaultMeaning
data_filekds.dbPath to the data file. Created if absent. Also set by the positional argument.
wal_dir<data_file>.walDirectory for the WAL segment files.
buffer_pool_framesnone (required)Maximum buffer pool size, in 8 KiB frames, shared by all cores. A config without it, or with 0, is refused. Resident pages never exceed it. A statement that needs more frames than the pool can free is refused ResourceExhausted. The floor is the volume’s resident pages (128 system pages plus every Bound Cabin page) plus 256 frames; a lower value is refused at mount, naming both numbers. Example: 131072 frames is 1 GiB of page memory.
inline_cell_width64Bytes every varchar cell occupies in a row, unless the column declares varchar(N). Range 16 to 4096. A value longer than width − 3 is stored out of line. Fixed when a new database is created: every later start compares the setting with the stored value and refuses to start if they differ. Changing it means rebuilding the database.

Cores

KeyDefaultMeaning
cores1Reactor threads, one pinned per CPU. Range 1 to 64, and not more than the machine reports. All cores share one WAL stream, owned by core 0. Every core accepts connections on port (with SO_REUSEPORT above one core). The count can change between starts; the new count is recorded and logged.
reactor_cpusunsetThe CPU each reactor is pinned to, core 0 first, for example 0,2. Must name exactly cores distinct CPUs that the machine has. Unset, reactor k above 0 runs on CPU k and core 0 runs unpinned.

WAL and durability

KeyDefaultMeaning
durabilitygroupDefault durability class: strict/d1, group/d2 or relaxed/d3. Applied at COMMIT. A session overrides it with SET DURABILITY, and one transaction with BEGIN ... DURABILITY. See Choose a durability class.
wal_drain_interval_us1000How often the WAL drain runs, in microseconds. Bounds a relaxed commit’s loss window. 0 disables it, leaving relaxed commits unsynced until the next checkpoint or shutdown.
relaxed_flush_interval_us10000How long a relaxed commit may stay unsynced, in microseconds. The sync runs on the reactor thread, so this is also a latency setting.
checkpoint_interval_ms5000How often dirty pages are flushed to the data file. 0 disables the cadence.
archive_dirunsetWAL archive directory. Every sealed segment is copied there and synced. See Back up and restore.
archive_commandunsetShell command that archives one segment; %p is its path and %f its name. Exit status 0 means durable. Setting both archive keys is refused.

Transactions and waits

KeyDefaultMeaning
isolationread committedIsolation level a session starts at: read committed or repeatable read. Case-insensitive; - and _ are accepted for the space. serializable and read uncommitted are refused by name.
lock_wait_fault_net_ms1000How long a statement may wait for a row, range or table before the wait is treated as a fault. A normal wait ends when the holder commits or rolls back; this bound is for a holder that never decides. It aborts the waiter, never the holder. 0 refuses at once instead of waiting.
txn_lifetime_ceiling_ms60000Maximum age of an explicit transaction, counted from BEGIN. An older transaction is rolled back by the server, and the client’s next statement, COMMIT included, is refused RESOURCE_EXHAUSTED until it sends ROLLBACK. Checked every quarter of the ceiling, so a transaction ends between 1× and 1.25× of it. Autocommit statements and bulk-load sessions on kwp_port are exempt. 0 is refused.
max_locks_per_txn65536Lock-table entries one transaction may hold: one per table it writes and one per row. At the cap the statement is refused ResourceExhausted, not retryable. A write whose WHERE names a primary-key range takes one entry for the range. 0 is refused.

Network, TLS and authentication

KeyDefaultMeaning
port15432TCP port, range 1 to 65535. Loopback only. Speaks the binary protocol KWP/1.
tcp_keepalive_s60Seconds of silence before a client socket is probed. A client that vanished is closed after about twice this. A live client that leaves a reply unread for that long is also closed. There is no idle-session timeout. 0 turns keepalive off; above 32767 is refused.
tlsoffDirect TLS 1.3 on port. With on, every connection must start with a TLS handshake; plaintext clients are refused. Requires both file keys below. A build with -DKDS_WITH_TLS=OFF refuses on.
tls_cert_fileunsetPEM certificate, leaf first, chain appended. Read once at startup.
tls_key_fileunsetPEM private key, unencrypted. Read once at startup.
authoffoff admits every connection as admin. scram requires a SCRAM-SHA-256 exchange before the first statement.
users_fileunsetUser store for auth = scram: one <username> <role> <verifier> per line. Required and non-empty with scram. Written by kds_server --add-user, never by the running server. Roles are readonly, readwrite and admin.
debug_text_port0Port for the newline text protocol, a loopback debug surface. 0 opens no socket. STOP as a typed newline command needs this port; over KWP, STOP is sent as an ordinary statement.
kwp_port0Port for the KWP v0 bulk-load endpoint. 0 opens no socket. It has no authentication of its own, so auth = scram with a nonzero kwp_port is refused.

Statement limits

What happens at each cap is listed in Limits.

KeyDefaultMeaning
max_rows_touched100000000Rows one statement may read before it is refused ResourceExhausted. 0 means unlimited.
max_insert_rows1024Rows in one multi-row INSERT ... VALUES. Over the cap, the whole statement is refused. Must be at least 1.
sort_max_rows1048576Rows one ORDER BY may hold. Over the cap, the statement fails. 0 refuses every statement that needs a sort.
aggregate_max_groups65536Groups one aggregated statement may hold. Over the cap, the statement fails. 0 refuses every aggregated statement.
aggregate_max_distinct1048576DISTINCT entries one statement may hold, summed over all its sets. Over the cap, the statement fails.
join_build_max_rows65536Rows in the in-memory map a join builds for an inner table with no index and no Cabin. Over the cap, the join falls back to per-row walks; no statement is refused. 0 disables the map.
cabin_max_values4096Distinct values one Cabin may observe. Over the cap, the value is not observed and is served by a scan. 0 observes nothing.
cabin_max_entries_per_value4096Entries per value in one Cabin. Same behavior as above.

Access paths and optimizers

KeyDefaultMeaning
indexesonWhether secondary indexes may be read. off takes the walk instead; replies are identical. Indexes are still maintained; to stop that, DROP INDEX.
cabinsonWhether Cabins may be built and served. Does nothing until a Cabin is created.
waystone_recordingonWhether a successful SELECT records a trail for its pattern.
waystone_replayonWhether a SELECT may be served from a recorded trail. Neither Waystone switch changes any reply.
access_statisticsonRecords access shapes for SHOW ACCESS. Costs about 1–2% on a point lookup.
physical_optimizershadowoff or shadow. Shadow computes the SHOW RELAYOUT report on request and moves nothing. on is refused at startup, naming the three gates that block every plan.
decay_half_life600Seconds for an unused decay score to lose half its weight. 0 is refused.
cabin_optimizeroffWhether the Cabin optimizer may create, extend, heal and drop Cabins for CABIN AUTO columns. SET CABIN_OPTIMIZER ON or OFF changes it at runtime.

Cabin optimizer tuning

KeyDefaultRange and meaning
cabin_optimizer_page_budget1024Pages the optimizer may use for the Cabins it manages. Must be positive.
cabin_optimizer_theta_create_pct300Benefit/cost ratio, in percent, to create a Cabin. 1 to 100000.
cabin_optimizer_theta_drop_pct50Ratio below which a Cabin is dropped. 1 to 100000. Validation requires drop < 100 < create.
cabin_optimizer_theta_swap_pct200Swap threshold, in percent. 1 to 100000.
cabin_optimizer_theta_extend_pct20Extend threshold, in percent. 1 to 100000.
cabin_optimizer_theta_heal_pct10Heal threshold, in percent. 1 to 100000.
cabin_optimizer_confirm_snapshots3Snapshots that must agree before a decision. 1 to 1000.
cabin_optimizer_snapshot_interval_ms10000How often the optimizer takes a snapshot. 0 means no cadence.
cabin_optimizer_amort_windows64Decay half-lives a Cabin’s build cost is spread over. 1 to 100000.
cabin_optimizer_cooldown_half_lives128Half-lives a decaying Cabin is kept before it is dropped. 0 to 100000. At the default half-life, 128 is 21 h 20 min. Lowering it below about one night of half-lives drops Cabins that are only idle overnight.

Logging

KeyDefaultMeaning
log_diremptyPrepended to log_file unless that path is absolute. Created if missing.
log_filekdb.logLog file name. Empty disables file logging. Opened append-only.
log_levelinfotrace, debug, info, warn, error or off. info logs lifecycle events, debug one line per request, trace lines per row (a development tool).

Retired keys

These keys are refused by name at startup. The message says what replaced each one. Delete the line.

KeyWhy it is refused
in_doubt_ceiling_msReplaced by lock_wait_fault_net_ms.
peer_listenersEvery core now accepts on port.
placementNo table is owned by a core.
range_size_idsInsert spreading was removed.
default_key_modeThere is no key mode: every table takes a supplied primary key or issues one.

Command-line flags

kds_server [<data_file>] [--config <path>] [--port <n>] [--debug-text-port <n>]
           [--log-file <name>] [--log-dir <dir>] [--log-level <level>]
kds_server --add-user <name> [--role readonly|readwrite|admin] [--users-file <path>] [--config <path>]
kds_server --restore-from <backup_dir> [--restore-data <file>] [--restore-archive <dir>]
           [--restore-target <lsn>|latest] [--restore-only] [<data_file>] [--config <path>] ...
kds_server --verify-backup <backup_dir>
FlagOverrides or does
<data_file>data_file.
--config <path>Reads the config file.
--port <n>port.
--debug-text-port <n>debug_text_port.
--log-file, --log-dir, --log-levellog_file, log_dir, log_level.
--add-user <name>Adds a SCRAM user to the users file, prompting for the password, then exits. The server does not run.
--role <role>Role for --add-user. Default readonly.
--users-file <path>users_file.
--restore-from <dir>Restores a backup into the configured data_file and wal_dir, which must be empty, then serves.
--restore-data <file>A snapshot backup’s data file, when the backup does not hold it.
--restore-archive <dir>WAL archive to read for a target past the backup’s stop.
--restore-target <lsn>|latestReplay to the first record at or past the LSN, or through every archived segment.
--restore-onlyExit after the restore’s recovery instead of serving.
--verify-backup <dir>Checks a backup and exits.
--help, -hPrints usage.

Example

# kds.conf
data_file = /srv/kds/kds.db
buffer_pool_frames = 131072
cores = 1
durability = group
checkpoint_interval_ms = 5000
log_dir = /var/log/kds
log_level = info
./build/kds_server --config kds.conf --port 15433

The flag sets the port to 15433 for this run, whatever the file says.