Skip to content

Run kinedb

kinedb is one program, kinedb. The same program is a server, a node of a cluster, a SQL shell, and an embedded engine for one-off SQL. This page tells how to start it, and it lists every command-line argument and every environment variable.

Get kinedb

Today the only distribution is a container image. The pull needs no login:

sh
docker pull git.kinedb.com/kinedb/kinedb:latest
  • Tags. latest, and one tag per build: the first 12 characters of its git commit.
  • Content. The static kinedb binary at /app/kinedb, and the web console with these docs at /app/dist. The image is built for linux/amd64.
  • Defaults. The image runs as the user 65532. Its default command is --port 4820 --data-dir /data, and /data is a volume.

The binary in the image is static, so you can copy it out and run it on any x86-64 Linux:

sh
id=$(docker create git.kinedb.com/kinedb/kinedb:latest)
docker cp "$id":/app/kinedb ./kinedb
docker rm "$id"

One server

sh
docker run -d --name kinedb -p 4820:4820 -v kinedb-data:/data \
  -e KINEDB_ROOT_PASSWORD='choose-a-password' \
  git.kinedb.com/kinedb/kinedb:latest

Or with the binary:

sh
KINEDB_ROOT_PASSWORD='choose-a-password' ./kinedb --port 4820 --data-dir ./data
  • Without --data-dir, the data stays in memory, and it is lost when the process stops.
  • One port carries everything: the clients, the peers, the web console at /ui/, and these docs at /ui/docs/.

Log in

Clients must log in by default (KINEDB_CLIENT_AUTH=required).

The first boot creates the user root. With KINEDB_ROOT_PASSWORD, root gets that password. Without it, the server makes a password and writes it once to its log:

sh
docker logs kinedb 2>&1 | grep 'GENERATED password'

The SQL shell reads the password from KINEDB_ROOT_PASSWORD and logs in as root. Use --user and --password-env for another user. There is no password prompt.

sh
docker exec -it kinedb /app/kinedb --connect 127.0.0.1:4820
docker exec kinedb /app/kinedb --connect 127.0.0.1:4820 -e "SHOW DATABASES"

Over HTTP, POST /login gives a token, and every other request carries it:

sh
curl -s -X POST http://localhost:4820/login \
  -d '{"username": "root", "password": "choose-a-password"}'
# the answer is a JSON object with a "token"

curl -s -X POST http://localhost:4820/sql \
  -H "Authorization: Bearer <token>" \
  --data-binary 'SHOW DATABASES'

An application uses a client library: JavaScript or Python.

KINEDB_CLIENT_AUTH=permissive turns the login off: then anyone who reaches the port can read and write. Use it only on a network that you trust.

A cluster

A cluster is any number of kinedb nodes. To start one:

  1. Choose a cluster secret. Give every node the same KINEDB_CLUSTER_SECRET. Peer authentication is on by default, and a cluster node without a secret refuses to start.
  2. Start the first node with --calvin.
  3. Start every other node with --calvin --join <host:port of a running node>.
  4. Set KINEDB_ADVERTISE_ADDR on every node to the address that the other nodes use to reach it. A node that listens on all interfaces, which includes every container, otherwise tells its peers 127.0.0.1.

Three hosts, 10.0.0.1 to 10.0.0.3, with Docker:

sh
# on 10.0.0.1: the first node
docker run -d --name kinedb -p 4820:4820 -v kinedb-data:/data \
  -e KINEDB_CLUSTER_SECRET='a-long-random-secret' \
  -e KINEDB_ROOT_PASSWORD='choose-a-password' \
  -e KINEDB_ADVERTISE_ADDR=10.0.0.1 \
  git.kinedb.com/kinedb/kinedb:latest --port 4820 --data-dir /data --calvin

# on 10.0.0.2 (and the same on 10.0.0.3, with its own address)
docker run -d --name kinedb -p 4820:4820 -v kinedb-data:/data \
  -e KINEDB_CLUSTER_SECRET='a-long-random-secret' \
  -e KINEDB_ROOT_PASSWORD='choose-a-password' \
  -e KINEDB_ADVERTISE_ADDR=10.0.0.2 \
  git.kinedb.com/kinedb/kinedb:latest --port 4820 --data-dir /data --calvin --join 10.0.0.1:4820

Arguments after the image name replace the default command, so they repeat --port and --data-dir.

  • Ports. The nodes talk to each other on the same TCP port as the clients. There is no other port to open.
  • Replicas. Each shard has 3 replicas by default. KINEDB_REPLICATION_FACTOR sets the first value on a new cluster; after that, SET CLUSTER cluster.replication_factor = <n> changes it.
  • Joining. A joining node waits 10 seconds for the leader to accept it, and then it exits with an error (KINEDB_JOINER_BOOT_TIMEOUT_MS).
  • Durability. A write is durable when the cluster acknowledges it: each replica writes the entry to disk before it counts toward the quorum. Each node keeps its Raft log in <data-dir>/raft_wal.

Embedded: SQL without a server

With -e or -f and without --connect, kinedb runs the SQL in its own process and exits. No server starts, and no port opens. With --data-dir, the data stays for the next call.

sh
./kinedb --data-dir ./data -e "CREATE TABLE t (id INT, name TEXT, PRIMARY KEY (id))"
./kinedb --data-dir ./data -e "INSERT INTO t (id, name) VALUES (1, 'a'); SELECT * FROM t"
./kinedb --data-dir ./data -f setup.sql
  • -e splits the SQL on ; and runs the statements in order. -f file.sql does the same with a file, and -f file.kd runs a kd script.
  • -e stops at the first statement that fails. It prints a line that starts with ERROR:, and it exits with 1.
  • Some statements need a server; the SQL reference marks them.

In Rust, the kinedb crate is the same engine as a library (Db::open(path), db.execute(sql)).

Command-line arguments

ArgumentDefaultWhat it does
--port PORT4820The TCP port for the clients, the peers, the web console and these docs.
--data-dir DIRnot setThe directory of the data. Without it, the data stays in memory.
--memory SIZEnot setThe total memory budget of the process, for example 4GB or 3800MB. kinedb enforces it with its own accounting. It needs --data-dir, and it does not work with --s3 or --connect.
--cache-slab SIZEnot setA block cache that is allocated at start. Under --memory, it must fit the budget. Alone, it is the older way to size the cache.
--gc-retention SPECnot setTurns on the garbage collection of dead blocks, and sets the history to keep: <N>commits (the head and N older commits; 0commits keeps only the head) or <N>s, <N>m, <N>h, <N>d (for example 7d). Without it, nothing is reclaimed.
--calvinoffCluster mode: Raft and the deterministic sequencer. Every node of a cluster needs it.
--join HOST:PORTnot setJoin a cluster through a running node. Use it with --calvin.
--peer-auth MODErequiredrequired: the nodes must prove that they know the cluster secret. permissive: they need not.
--cluster-key KEYkinedbThe name of the cluster. A node ignores the gossip of a node with another key. It is not a secret.
--realm NAMEnot setThe realm of the node. Leave it unset for one realm.
--s3 URInot setStore the blocks in S3: s3://KEY:SECRET@HOST/BUCKET/PREFIX?region=R. --data-dir is then the local cache; without it, a temporary directory.
--webroot DIRfoundThe directory of the web console. Without it, kinedb looks for dist next to the binary, then for dist and web/dist in the working directory.
--no-weboffServe no web console and no docs.
--connect HOST:PORT, -cnot setClient mode: open a SQL shell on a running server, or run -e or -f there.
--user NAMErootClient mode: the user to log in as.
--password-env VARKINEDB_ROOT_PASSWORDClient mode: the environment variable that holds the password.
-e SQLnot setRun SQL and exit. Without --connect, the SQL runs in this process.
-f FILEnot setRun a file and exit: .kd is a kd script; any other file is SQL.
--show-typesoffClient mode: put the column type in the header of a result, for example price:Float.
--help, -hPrint the usage and exit.

Environment variables

Setup

VariableDefaultWhat it does
KINEDB_ROOT_PASSWORDnot setThe password of root, set at the first boot. Without it, the first boot makes a password and logs it once. The SQL shell also reads it to log in.
KINEDB_CLIENT_AUTHrequiredrequired: clients must log in. permissive: anyone can query.
KINEDB_PEER_AUTHrequiredThe same as --peer-auth. The flag wins.
KINEDB_CLUSTER_SECRETnot setThe secret that the nodes of a cluster share. It is only an environment variable, so it does not show in a process list.
KINEDB_ADVERTISE_ADDRnot setThe address that the peers use to reach this node, host or host:port (the port part is ignored). Without it, a node that listens on all interfaces advertises 127.0.0.1.
KINEDB_GC_RETENTIONnot setThe same as --gc-retention. The flag wins.
KINEDB_RAFT_WAL_DIR<data-dir>/raft_walThe directory of the Raft logs. Without a data directory and without this variable, the Raft log stays in memory.
KINEDB_LOG_SINKnot setws://host:port of a kinedb server that collects logs and metrics. With it, the node sends its logs and metrics there.
KINEDB_LOG_SINK_USER, KINEDB_LOG_SINK_PASSWORDnot setThe login at the log sink.

Tuning

These variables belong to the settings of the server; SHOW SETTINGS lists the same settings with the values in force. A variable of a cluster. setting sets the first value on a new cluster; after that, SET CLUSTER <setting> = <value> changes it. A node reads the variable of a node. setting when it starts.

VariableSettingDefaultWhat it does
KINEDB_CALVIN_APPLY_TIMEOUT_SECScluster.calvin.apply_timeout_secs60 secsHow long a Calvin write waits for local apply before returning an error.
KINEDB_SEQUENCER_BATCH_AGE_MScluster.calvin.sequencer_batch_age_ms2 msMaximum age (ms) a sequencer batch waits before flushing.
KINEDB_SEQUENCER_BATCH_SIZEcluster.calvin.sequencer_batch_size1024Maximum number of operations in a single Calvin sequencer batch.
KINEDB_FORCE_QUORUMcluster.quorumnot setRecovery only: forces cluster.quorum on this node for the life of the process.
KINEDB_REPLICATION_FACTORcluster.replication_factor3Number of Raft voter replicas per shard (RF<N mode).
KINEDB_FORCE_REPLICATION_FACTORcluster.replication_factornot setRecovery only: forces cluster.replication_factor on this node for the life of the process.
KINEDB_SPLIT_COOLDOWN_SECScluster.split.cooldown_secs60 secsHow long (secs) after a successful split before the same shard can be split again.
KINEDB_SPLIT_INTERVAL_MScluster.split.interval_ms10000 msHow often (ms) the SplitManager wakes to check if any shard has crossed the split threshold.
KINEDB_SPLIT_MAX_CONCURRENT_APPLIEScluster.split.max_concurrent_applies2How many split applies this node may have in flight at once.
KINEDB_MAX_SHARDScluster.split.max_shards256Global cap on the total number of shards.
KINEDB_SPLIT_THRESHOLD_BYTEScluster.split.threshold_bytes67108864 bytes (64 MiB)Shard size (bytes) at which the SplitManager proposes an automatic split.
KINEDB_FLUSH_GENERATION_BYTEScluster.storage.flush_generation_max_bytes67108864 bytes (64 MiB)Payload-byte bound on ONE flush generation.
KINEDB_FLUSH_GENERATION_KEYScluster.storage.flush_generation_max_keys512000Key-count bound on ONE flush generation, the companion to flush_generation_max_bytes — tree-mutate cost tracks KEYS while block-write cost tracks BYTES, and neither rate alone predicts cycle time across row shapes, so both are checked and whichever binds first rotates.
KINEDB_PER_SHARD_MEMTABLE_BYTES_LIMITcluster.storage.memtable_max_bytes268435456 bytes (256 MiB)Per-shard memtable byte cap.
KINEDB_SEQUENCER_PENDING_BYTES_LIMITcluster.calvin.sequencer_pending_bytes_limit536870912 bytes (512 MiB)Per-shard Calvin sequencer staging-buffer byte cap.
KINEDB_RAFT_LOG_PENDING_BYTES_LIMITcluster.calvin.raft_log_pending_bytes_limit536870912 bytes (512 MiB)Per-shard cap on bytes the leader has proposed but not yet replicated to min(match_index) across peers.
KINEDB_RAFT_LOG_COMPACTION_BYTEScluster.calvin.raft_log_compaction_bytes67108864 bytes (64 MiB)Per-shard byte budget for the byte-aware raft-log compaction trigger.
KINEDB_RAFT_LOG_MARGIN_BYTEScluster.calvin.raft_log_margin_bytes4194304 bytes (4 MiB)Byte budget for the raft-log compaction SAFETY MARGIN — the trailing band each shard holds ABOVE effective_floor so a briefly lagging peer can still be served by AE retransmit.
KINEDB_RAFT_LOG_COMPACTION_NODE_BYTEScluster.calvin.raft_log_compaction_node_bytes536870912 bytes (512 MiB)Node-wide ceiling on the sum of every local shard's retained raft-log body.
KINEDB_PEER_BROADCAST_QUEUE_BYTES_LIMITcluster.calvin.peer_broadcast_queue_bytes_limit1073741824 bytes (1 GiB)Per-peer outbound broadcast-queue byte cap.
KINE_DIAGnode.diag.diagfalseEnable diagnostic logging mode (presence of KINE_DIAG enables).
KINE_TRANSFER_LOGnode.diag.transfer_logfalseEnable verbose logging of shard transfer operations (KINE_TRANSFER_LOG).
KINEDB_RAFT_ELECTION_USnode.raft.election_us5000000 usRaft election timeout in microseconds.
KINEDB_RAFT_HEARTBEAT_USnode.raft.heartbeat_us500000 usRaft leader heartbeat interval in microseconds.
KINEDB_JOINER_BOOT_TIMEOUT_MSnode.raft.joiner_boot_timeout_ms10000 msHow long (ms) a joining node waits to receive its first AppendEntries before giving up and exiting with an error.
KINEDB_JOIN_PIN_BUDGET_MSnode.raft.join_pin_budget_ms60000 msHow long (ms) a shard leader holds the Raft-log compaction floor pinned for a reserved joiner.
KINEDB_JOIN_PIN_WAIT_MSnode.raft.join_pin_wait_ms5000 msHow long (ms) ONE shard acquisition waits for a peer that can serve a snapshot at or above the reserved pin.
KINEDB_RAFT_SWIM_POLL_MSnode.raft.swim_poll_ms500 msHow often (ms) the Raft membership observer polls SWIM state to detect peer additions and removals.

The server reads more KINEDB_* variables for diagnostics, tests and recovery. They are not a stable interface, and this page does not list them.

Ports and endpoints

Everything uses one TCP port, 4820 by default.

PathWhat it is
GET /healthHealth check. It needs no login.
POST /login{"username": ..., "password": ...} in, a token out.
POST /sqlSQL text in, JSON out. Send Authorization: Bearer <token>.
/wsA WebSocket with the binary protocol of the client libraries. Live queries (WATCH) use it.
/ui/The web console.
/ui/docs/These docs, for the version of this node. /ui/docs/llms-full.txt holds all pages in one file.