# The kdb program > What the kdb program is, how it finds your databases, and what its exit codes mean. - Category: Command line - Keywords: command line, CLI, kdb.exe, usage, exit code, $LASTEXITCODE, data folder, KDB\_DATA\_DIR, --data-dir, --config, kdb.conf, database name, folder path, --help, -h, --version, kdb help, kdb help tutorial - See also: [kdb sql and kdb shell](cli-sql-and-shell.md), [kdb serve](cli-serve.md), [kdb info, check, repair, dump-file](cli-maintenance.md), [kdb user](cli-users.md), [Backup, check, repair and restore](backup-and-safety.md), [Databases and the data folder](databases.md) `kdb` is the one program you need. It runs SQL, the interactive shell, the server, backups and repairs. It works in PowerShell, CMD, bash and zsh, on Windows, Linux and macOS. A **database** is a folder on the disk. Many databases can live in one **data folder** (one sub-folder per database). Most commands take a `` argument: the **name** of a database in the data folder, or the **path** of a database folder. | Command | What it does | Help | |---|---|---| | `kdb sql` | Runs SQL once and prints the result | [kdb sql](cli-sql-and-shell.md#kdb-sql) | | `kdb shell` | A prompt where you type SQL | [kdb shell](cli-sql-and-shell.md#kdb-shell) | | `kdb serve` | The server: web console, HTTP API, PostgreSQL port | [kdb serve](cli-serve.md#kdb-serve) | | `kdb info`, `kdb check`, `kdb repair`, `kdb dump-file` | Look at a database, find and fix damage | [maintenance](cli-maintenance.md) | | `kdb backup`, `kdb backups`, `kdb verify-backup`, `kdb restore` | Backups | [backup and safety](backup-and-safety.md) | | `kdb user ...` | Users of the server | [kdb user](cli-users.md) | | `kdb version`, `kdb help []` | Version; the list of commands and of every help topic, one topic, or a tutorial chapter, in the terminal | below | | `kdb upgrade` | Make an older database ready for this KDB (backup, feature list, check) | [versions and upgrades](versions.md) | | `kdb features` | The stored-format features a database uses now, and what uses them | [going back](versions.md#downgrade) | | `kdb downgrade` | Let an older KDB open the data again, when it uses nothing newer (backup, feature list, check) | [going back](versions.md#downgrade) | | `kdb skill`, `kdb skill install` | Print, or install for Claude Code, the file that teaches an AI assistant how to use KDB | [the Claude skill](install-packages.md#skill) | ## kdb help Syntax: ```sql kdb kdb help kdb --help kdb -h kdb help kdb help tutorial [] ``` Prints the version and a short list of every command and option, then the list of help topics - the same pages a running server shows at `/help` - with their titles. `kdb help ` prints one topic in the terminal (the Markdown source in a source checkout, the built page as text in a package); a word that is not a topic lists the topics whose name contains it. `kdb help tutorial` lists the tutorial chapters and `kdb help tutorial 17` prints one (the tutorial is part of the source checkout only). - **Exit code:** `0` for `kdb help`, `--help` and `-h`. `1` for `kdb` with no command, for an unknown command, and for a topic that does not exist. - **Notes:** an unknown command (for example a typing mistake like `kdb bakup`) also prints this list, with exit code `1`. The topics come from the help folder the program finds (`help_dir` in kdb.conf, `KDB_HELP_DIR`, next to the program, or the checkout's `docs/help/site`); without one, only the command list is printed. **Command line: The list of commands** ```bash kdb help ``` Output: ```text kdb 0.2.0-dev Usage: kdb info show files, versions and log position kdb check [--no-audit-chain] read every block and log record, report damage; then check the hash chain of _audit_log kdb repair [--backups ] [--accept-log-loss] fix damaged files from old versions or backups kdb backup [--hard-links] [--keep-daily N] [--keep-weekly N] kdb backups list backups, newest first kdb verify-backup kdb restore [--logs-from ] [--until "YYYY-MM-DD HH:MM[:SS]"] kdb dump-file header and block checksums of one file kdb serve [] [--db ] [--port 9900] [--bind 127.0.0.1] [--backups ] [--token ] [--memory ] [--sync-commits always|batch] [--threads N] HTTP API, line protocol (POST /write) and web console [--pg-port 8832] [--pg-timestamptz] PostgreSQL protocol for Postgres drivers and tools (0 = off) (Ctrl+C stops). Without : every database in the data folder kdb promote [--url http://localhost:9900] [--token ] make the standby at --url a primary: it stops copying and takes changes (when the primary is lost) kdb shell [] [--backups ] [--memory ] interactive SQL prompt (end statements with ;) kdb sql "SQL" [--format table|csv|json] [--max-rows N] run SQL and print results (use - to read SQL from stdin) kdb user add [--role admin|ddl|write|read] add a server user; the password is asked for (or read from a pipe), never given on the command line kdb user passwd set a new password kdb user role admin|ddl|write|read|none change the role kdb user list users and roles (never passwords) kdb user remove kdb user reset-2fa turn two-factor login off (a lost phone) (kdb user works on the data folder while kdb serve is stopped; while it runs, use CREATE USER ... in its console) kdb version [] this build and the stored-format features it reads; with : the features that database uses kdb upgrade [--backups ] verified backup, then save the database's feature list, then check kdb features | --data-dir the stored-format features each database uses now, and what uses them kdb downgrade | --data-dir --to [--backups ] [--no-backup] let an older KDB open the data (--to 2026-09-13, or --known from the older kdb version); refused, naming what uses each newer feature, when the data needs one kdb key new print a new random master key (64 hex characters) for encrypted databases: keep it in KDB_MASTER_KEY or a key file (KDB_MASTER_KEY_FILE) outside the data folder kdb key rotate re-wrap the data key of an encrypted database folder, or of every backup in a folder of backups, with KDB_MASTER_KEY (the old key in KDB_MASTER_KEY_PREVIOUS); no data file changes kdb help [ | tutorial []] the help topics (and, in a source checkout, the tutorial) in the terminal; without a topic: the list of topics kdb skill [install] [--dir ] [--url ] [--token ] [--home ] print, or install into ~/.claude/skills/kdb, the file that teaches an AI assistant in another project how to use KDB : a database name in the data folder (market), or the path of a database folder (D:\kdb\market, ./market). Data folder: --data-dir , else kdb.conf, else the KDB_DATA_DIR environment variable, else "data" next to kdb. --config : kdb.conf, the JSON file the console's Settings page and ALTER SYSTEM write (default: kdb.conf next to kdb). A flag on the command line always wins over it, and it wins over the environment. It may hold: data_dir, wal_dir, wal_archive_mb, cache_mb, keep_versions, trash_keep_hours, trash_max_mb, slow_query_ms, http_threads, max_connections, lock_timeout_ms, idle_in_transaction_timeout_ms, rate_limit_ip, rate_limit_user, timer_workers, timezone, http_functions, http_timeout_ms, ilp_auto_create, step_up_actions, step_up_minutes, alert_webhook, tls_cert, tls_key, the backup_* settings, and "system" (what ALTER SYSTEM SET saved; SELECT pg_reload_conf() puts it in use). A database folder served by its path (kdb serve D:\kdb\market) reads only the three folders below. web_dir, help_dir and skill_dir name the folders of the console, the help and the Claude skill (else KDB_WEB_DIR, KDB_HELP_DIR, KDB_SKILL_DIR, else web/, help/ and skill/ next to kdb). --memory : memory for table data kept loaded (default 512). More is faster on big tables. --memory-limit : one limit for everything the server holds (table data, unsaved changes, indexes, results, caches, what the allocator keeps), like 3GB or 3072 (MB). Near it, memory is given back (the result cache too); at it, quick statements still run in a small reserve and others get 'memory full' (HTTP 503, PostgreSQL 53200); over it, the running statement that holds the most is stopped with 'memory full'. Default: 85% of a container's memory limit, else of the machine's memory (env KDB_MEMORY_LIMIT; 0 or off = no limit). --threads : threads for big queries and writes (default and most: half of the CPU threads). --cache-mb : memory for results of repeated queries, all databases together (default 256, 0 = off; else kdb.conf cache_mb, else env KDB_CACHE_MB). A result is used again only while no table it read has changed; a quick one (under 1 ms) is kept when asked twice. Queries with random() are never kept; with now() only for a caller that takes an older answer (/exec?cache_now_ms=500, SET result_cache_now_ms = 500). One result may use a quarter of it, a pinned one three quarters. ALTER DATABASE db SET RESULT_CACHE = '256MB' gives a database a space of its own. --pg-compat on|off: PostgreSQL 14's answers for every database without its own ALTER DATABASE ... SET pg_compat (default off; env KDB_PG_COMPAT): 7 / 2 = 3, 1.005 is an exact NUMERIC, a window with ORDER BY counts ties together, text sorts like en_US. A session can choose with SET kdb.pg_compat = on | off. --pg-int-division on|off: on the Postgres port, whole number / whole number gives a whole number (7 / 2 = 3) as in PostgreSQL (default off; env KDB_PG_INT_DIVISION). A session can still choose with SET int_division = integer | float. --reader-yield on|off: readers do not wait for a long trigger or CALL; they read the last committed rows (default on; env KDB_READER_YIELD). Off: readers wait for the writer's statement. --per-table-reads on|off: a reader waits only for writers of the tables it reads, and not while a checkpoint writes its files (default on; env KDB_PER_TABLE_READS). Off: it waits for every writer. --pin-threads auto|on|off: auto (default): on Linux, inside a CPU quota (docker --cpus, cgroup cpu.max) smaller than the CPUs the process may run on, every thread is pinned to the quota's worth of CPUs, one per core, and moved back when the quota goes (docker update --cpus); 32 connections on a 2-CPU quota of a 32-CPU host no longer run on all 32 and stall when the time is spent. on: each HTTP worker, PostgreSQL connection and query thread runs on one CPU of its own, taken in turn from as many CPUs as KDB may use, out of the cpuset; background threads stay on those CPUs. off: nothing is pinned (env KDB_PIN_THREADS). Ignored on Windows. --read-only-calls on|off: a CALL of a procedure that changes nothing runs like a SELECT: no table locks, no transaction (default on; env KDB_READ_ONLY_CALLS). --scoped-ddl on|off: CREATE/ALTER/DROP TABLE, INDEX and TRIGGER, TRUNCATE, CREATE TABLE AS and materialized views lock only the tables they touch; views, procedures and functions lock none (default on; env KDB_SCOPED_DDL). Off: every schema change locks every table. --ddl-beside-writers on|off: with --scoped-ddl, CREATE TABLE, ALTER TABLE, RENAME TABLE and CREATE/DROP INDEX run beside a writer of other tables that is inside one long statement (default on; env KDB_DDL_BESIDE_WRITERS). Off: they wait until that writer pauses between two statements. --log-lock-waits on|off: a statement that waits for a table lock longer than --deadlock-timeout writes one line to the log naming itself, the lock and who holds it (default off; env KDB_LOG_LOCK_WAITS; a session: SET log_lock_waits = on). --deadlock-timeout 1s: when --log-lock-waits writes its line (default 1s; env KDB_DEADLOCK_TIMEOUT; a session: SET deadlock_timeout). Deadlocks are found at once whatever it is. --skip-locked-beside on|off: SELECT ... FOR UPDATE SKIP LOCKED inside BEGIN reads beside other open transactions that hold the table and returns the rows they did not touch (default off; env KDB_SKIP_LOCKED_BESIDE). Its UPDATE of such a row waits for their COMMIT. Off: no rows there. --table-writers one|many: many: several users change one table at the same time when each of their statements on it touches single rows by the primary key (one-row INSERT, UPDATE or DELETE ... WHERE id = x, a CALL or trigger of such statements); the same row is waited for, as in PostgreSQL. Anything else on the table waits for the whole table, as before (default one; env KDB_TABLE_WRITERS). --snapshot-reads on|off: a reader of a table that a long CALL, trigger job or bulk write is changing does not wait: it reads a snapshot of the committed rows (default off; env KDB_SNAPSHOT_READS). Tables with an index too, while a writer is busy on them, at any size: the read uses the index on the snapshot (an idle BEGIN is taken out and the index used, as before). --tail-files on|off: a checkpoint saves rows appended after the end of a partition in a small tail file instead of writing the whole partition again (default off; env KDB_TAIL_FILES). A database with tail files needs a KDB from 2026-10-02 or later (kdb downgrade merges them back). --snapshot-index-rows 1000000: a table with a full-text/JSON index, or an index not built yet, is scanned on a snapshot: only up to this many rows, a bigger one waits for its writer as before (default 1000000; 0 = indexed tables never get snapshots; env KDB_SNAPSHOT_INDEX_ROWS). --txn-spill-mb 64: a transaction's log records past this many MB (or 1/16 of --memory-limit) go to a temporary file in the database's _tmp folder until COMMIT (default 64; 0 = never; env KDB_TXN_SPILL_MB). --lanes on|off: priority lanes (default on; env KDB_LANES). A read whose shape used --heavy-ms of CPU or more the last three times it ran is heavy: only --heavy-slots of those run at once, at a lower CPU priority, and the rest wait in line. Charts and other short statements never wait. SET kdb.priority = high|normal|low, the X-KDB-Priority header and ALTER USER ... SET kdb.priority choose a lane by hand. Off: every statement runs at once. --heavy-ms 100: the CPU time a read shape must use to count as heavy (env KDB_HEAVY_MS). --heavy-slots N: heavy statements that run at once (default half the CPUs, at least 1; env KDB_HEAVY_SLOTS). --heavy-queue N: heavy HTTP requests that may wait at once (default half the HTTP threads, at least 4; env KDB_HEAVY_QUEUE). Past it a request sent with priority low gets 503; a read heavy by its history runs at once. PostgreSQL statements are not counted: they wait up to their timeout. --read-slots auto|off|N: reads (outside BEGIN) that run at once; the rest wait in line. A read holds its slot for at most 10 ms, so a long one never holds the line up (default auto = the CPUs the process may use, at least 2, following docker update --cpus; env KDB_READ_SLOTS). Off: every read starts at once, as before. --timezone Asia/Kathmandu: the clock of CURRENT_DATE, ::date, date_trunc, EXTRACT and to_char, and of timer and backup schedules (default: the computer's own zone; env KDB_TIMEZONE; kdb.conf "timezone"). Times are still stored as UTC. A session: SET TIME ZONE. Default: the computer's own zone. Zones with summer time (America/New_York) need the system's zone files (tzdata); per user: ALTER USER name SET timezone = 'zone'. --warm-indexes on|off: build every index right after a database opens, on a background thread, so the first query finds them ready (default on; env KDB_WARM_INDEXES). Off: on first use. --sync-commits always: every write is on disk before it is confirmed (default). --sync-commits batch: writes are confirmed at once and put on disk every 10 ms. Much faster for many small writes; a power cut can lose the last confirmed writes, but never damages the data. Protection of kdb serve (docs/tutorial/21-protection.md): --statement-timeout 60s stop statements that run longer (default 60s, 0 = no limit) --max-result-memory 1GB rows one query may keep in memory (default 1GB, 0 = no limit) --max-groups N GROUP BY groups of one query (default 5000000, 0 = no limit) --max-queries-per-user N statements one user runs at the same time (default 32, 0 = no limit) --safe-updates refuse UPDATE and DELETE without WHERE (SET safe_updates = off per session) --read-only the whole server only reads --standby-of URL this server is a standby: it copies every database of the primary at URL (http://host:9900) from its log, and only reads (env KDB_STANDBY_OF) --standby-token T the token the standby sends to the primary: its --token or an admin's API token (env KDB_STANDBY_TOKEN) --trash-days N DROP TABLE keeps the table N days for UNDROP TABLE (default 7; also sql, shell) --audit on|off audit log of logins, users, DDL, backups in _system (default on) --audit-keep-days N remove audit rows older than N days (default 0 = keep forever) --activity-log-size N recent events for the console's activity panel, in memory (default 5000, 0 = off) --slow-query-ms N statements taking N ms or more go to /_logs/slow_queries.jsonl (GET /api/slow-queries; default 1000, 0 = off; env KDB_SLOW_QUERY_MS) --stat-statements on|off pg_stat_statements: totals per statement shape, in memory (default on; env KDB_STAT_STATEMENTS) --token-name NAME what the audit log calls whoever uses the --token (default token; env KDB_TOKEN_NAME) --trash-max-mb N a database's _trash may hold N MB; beyond it the oldest go at once (default: a quarter of the data, at least 256 MB; 0 = no limit; env KDB_TRASH_MAX_MB, kdb.conf trash_max_mb) --drain-timeout 30s on stop, running requests may finish this long; new ones get 503 (default 30s) --tls-cert FILE --tls-key FILE TLS on both ports: https:// and PostgreSQL sslmode=require (PEM files; --tls-cert auto: a self-signed pair made in /_tls; env KDB_TLS_CERT, KDB_TLS_KEY; kdb.conf tls_cert, tls_key) --tls-required on|off with TLS, refuse plain connections except from 127.x (default on; env KDB_TLS_REQUIRED) --rate-limit-ip N requests per second one client address may send, HTTP and PostgreSQL (default 0 = no limit; 127.x is never limited; env KDB_RATE_LIMIT_IP) --rate-limit-user N requests per second one user may send (default 0 = no limit; env KDB_RATE_LIMIT_USER). Over a limit: HTTP 429 with Retry-After --http-threads N HTTP requests handled at once (default: the CPU threads, at least 8; env KDB_HTTP_THREADS) --http-gzip remote|on|off gzip answers of 2 KB or more for clients that send Accept-Encoding: gzip: clients on other computers (remote, the default), all, or none (env KDB_HTTP_GZIP) --timer-workers N timers that may run at the same time (1 to 64, default 3; env KDB_TIMER_WORKERS) --tcp-keepalives-idle S TCP keepalive of every connection: seconds idle before the first probe, --tcp-keepalives-interval S seconds between probes, and probes before a vanished client is dropped --tcp-keepalives-count N (0 = the system's, the default; env KDB_TCP_KEEPALIVES_IDLE, ...) --ilp-auto-create on|off POST /write creates a table it does not find, as QuestDB does (default on; kdb.conf "ilp_auto_create"; env KDB_ILP_AUTO_CREATE) --max-connections N PostgreSQL logins at once, all databases (default 100, 0 = no limit; env KDB_MAX_CONNECTIONS) --lock-timeout 5s a writer waits this long for a busy table (default 5s, 0 = no limit; env KDB_LOCK_TIMEOUT; a session: SET lock_timeout = '20s') --idle-in-transaction-timeout 30s an open BEGIN ... COMMIT that sends nothing this long is rolled back (default 30s, 0 = never; env KDB_IDLE_IN_TRANSACTION_TIMEOUT; a session: SET idle_in_transaction_session_timeout = '5min') --trigger-retries N a failed deferred trigger job runs again N times (1 s, 2 s, 4 s ... apart) before its queue stops (default 3, 0 = never; env KDB_TRIGGER_RETRIES) --max-trigger-jobs N deferred trigger jobs waiting per database; a write past it is refused with the reason (default 10000, 0 = no limit; env KDB_MAX_TRIGGER_JOBS) --alert-webhook URL POST failed trigger jobs as JSON to http://:/ (env KDB_ALERT_WEBHOOK, kdb.conf alert_webhook) --backups backup folder (default /_backups; "off" = none; or KDB_BACKUP_DIR) --backup-schedule "daily 16:00" verified backups of every database (local time; or KDB_BACKUP_SCHEDULE) --backup-command "" run after each backup to copy it off the server: {dir} {database} {name} (or KDB_BACKUP_COMMAND), e.g. "rclone copy {dir} remote:kdb/{database}/{name}" --backup-copy a second, checked copy of each scheduled backup (another disk) --backup-warn-hours N warn in the log when the last good backup is older (default 26) --keep-daily N --keep-weekly N backups kept (default 7 and 4; or KDB_BACKUP_KEEP_DAILY / _WEEKLY) Exit codes: 0 OK, 1 error, 2 damage found, 3 the database needs a newer KDB (nothing was changed). Help topics (0), from ./help-placeholder. "kdb help " prints one; a running server has them at /help: ``` ## kdb version Syntax: ```sql kdb version kdb --version kdb version ``` Prints the version of KDB and the stored-format features it can read. `crc32c hardware: yes` means the CPU computes checksums (CRC32C) with special fast instructions. `no` also works, only slower. With `` it shows the features that database uses ([versions and upgrades](versions.md)). - **Exit code:** `0`. With ``: `3` when the database needs a newer KDB. **Command line** ```bash kdb version ``` Output: ```text kdb 0.2.0-dev (crc32c hardware: yes) tls: OpenSSL 3.6.3 9 Jun 2026 Stored-format features this build reads (51): views 0.2.0-dev (2026-09-10) CREATE VIEW: the "views" file partition_format_2 0.2.0-dev (2026-09-11) table partition files in format 2 (one raw block per column) block_stats 0.2.0-dev (2026-09-11) column stats section in partition files (count, min, max, sum per column) runs 0.2.0-dev (2026-09-11) log record 'C': rows of a bulk upsert kept as columns auto_meta 0.2.0-dev (2026-09-11) AUTO id counters in the manifest (auto.) json 0.2.0-dev (2026-09-11) JSON columns (type code 12) bytes 0.2.0-dev (2026-09-11) BYTES columns (type code 13) check 0.2.0-dev (2026-09-11) CHECK constraints (catalog format 2, part 'C') indexes 0.2.0-dev (2026-09-11) CREATE INDEX, UNIQUE and FULLTEXT indexes (catalog part 'I') routines 0.2.0-dev (2026-09-11) functions, procedures and triggers: the "routines" file users 0.2.0-dev (2026-09-11) server users and roles (_system.users) audit 0.2.0-dev (2026-09-12) SET AUDIT ON: catalog part 'A', log record 'P', the _audit_log table table_grants 0.2.0-dev (2026-09-12) GRANT ... ON TABLE (_system.users.table_grants) totp 0.2.0-dev (2026-09-12) two-factor logins (_system.users.totp) trash 0.2.0-dev (2026-09-12) dropped tables kept as _dropped__ for UNDROP TABLE database_settings 0.2.0-dev (2026-09-12) ALTER DATABASE ... SET READ ONLY (_system.database_settings) dialects 0.2.0-dev (2026-09-12) ALTER DATABASE ... SET dialect (_system.database_dialects) pg_catalog_parts 0.2.0-dev (2026-09-12) PostgreSQL column types, multi-column keys, foreign keys, expression and partial indexes (catalog parts 'T', 'K', 'F', 'X') sequences 0.2.0-dev (2026-09-12) CREATE SEQUENCE: the "sequences" file and its log records batched_log_sync 0.2.0-dev (2026-09-11) log segments in the batched format (header flag 1, 16-byte commit records): group commit and --sync-commits batch dedup_change 0.2.0-dev (2026-09-12) ALTER TABLE ... DEDUP ENABLE / DISABLE: the DEDUP KEY of a table that already holds rows plpgsql_triggers 0.2.0-dev (2026-09-12) PostgreSQL plpgsql trigger functions and FOR EACH ROW triggers in the "routines" file cached_views 0.2.0-dev (2026-09-13) CREATE CACHED VIEW: which views are cached, and REFRESH ON COMMIT, in the "views" file deferred_triggers 0.2.0-dev (2026-09-13) CREATE TRIGGER ... DEFERRED: job records in the log, and the "trigger_queue" and "q/" files of queued jobs materialized_views 0.2.0-dev (2026-09-13) CREATE MATERIALIZED VIEW: catalog part 'M', REFRESH MATERIALIZED VIEW log records, mv_dirty. in the manifest table_ttl 0.2.0-dev (2026-09-13) TTL n DAYS on a table: catalog part 'L' read_only_procedures 0.2.0-dev (2026-09-24) CREATE PROCEDURE ... READ ONLY in the "routines" file dedup_insert 0.2.0-dev (2026-09-24) WITH (dedup_insert = 'upsert') on a table: catalog part 'U' decimal128 0.2.0-dev (2026-09-25) NUMERIC(p, s) columns with more than 18 digits: 128-bit DECIMAL (type code 14) in the catalog, partition files and log dedup_generated_key 0.2.0-dev (2026-09-25) a stored generated column in a DEDUP KEY, like the minute of the time (an older build refuses such a catalog) symbol_partitions 0.2.0-dev (2026-09-25) PARTITION BY