KDB knowledge

Web console

The browser page of kdb serve - run SQL, see results as a grid or a chart, switch databases, check health, make backups and open this help.

The web console is a web page inside kdb serve. Open it in a browser to write SQL, run it, and look at the results. It needs no internet and no other software. Its files are plain files in the folder web/ next to the kdb program, not inside the program (where kdb finds them).

Pick a page from the Home menu at the top left. The button shows where you are, for example Home / Dashboard.

Menu itemWhat it is for
Homewrite and run statements, see results as a grid or a chart (this page)
Dashboardmany charts on one page, saved in the database
View databrowse tables and change rows with forms instead of SQL
Keep datahow long each table keeps its rows: keep the last months or years, drop what is older
Settingswhere the data is kept, how much old log each database keeps, and who may log in

The buttons down the right side open panels over the page: Monitor, Health, Samples, Databases, Tools and the Terminal (right side).

Comments and suggestions in the Help menu opens one more page: a form to send a message to whoever runs the server (feedback).

The page you were on last opens again when you come back.

Command line: Start the server; the console address is on the second line

kdb serve --backups backups

Output:

KDB 0.2.0-dev
  console   http://127.0.0.1:9900
  data      ./kdb-data (from KDB_DATA_DIR; one folder per database)
  default   default (used when a request names no database)
  backups   backups/<database name> (from --backups)
  access    no token
  capacity  32 HTTP threads (default), 500 PostgreSQL connections (default), lock wait 5 s (default)
  lanes     reads using 100 ms of CPU (three times in a row) wait for one of 16 heavy slots, at most 16 HTTP in line (--lanes on)
  reads     32 reads run at once (the CPUs, at least 2; follows the CPU limit), the rest wait in line (--read-slots)
  commits   synced to disk before they are confirmed (--sync-commits always)
  time zone Asia/Katmandu (the computer's); also timers and backup schedules
  readers   read while a long trigger or CALL writes (--reader-yield on); idle open transaction rolled back after 30 s (default)
  memory    26.95 GB for the whole process (85% of the machine's memory); table data 512.0 MB of it (--memory)
  cpu       32 CPUs (the machine's); 16 query threads (half of the CPUs, follows the limit), limits checked every 10 s
  limits    statement timeout 1 min, result memory 1.00 GB, 5000000 groups, 32 statements per user
  safety    writes allowed; DROP TABLE kept 7 days (UNDROP TABLE); audit log on (SHOW AUDIT)
  logs      slow queries >= 1000 ms to ./kdb-data/_logs/slow_queries.jsonl; pg_stat_statements on; metrics at /metrics
  recovery  the default database is created when it is first used

Press Ctrl+C to stop.

Open the console

Syntax:

kdb serve [<database folder>] [--data-dir <folder>] [--port 9900] [--bind 127.0.0.1] [--backups <folder>] [--token <secret>]
http://127.0.0.1:9900/
Server started asWhat the console shows
kdb serve or kdb serve --data-dir <folder>every database of the data folder; New database is there
kdb serve D:\kdb\market (one folder)just that database; no New database
with a data folder (or --backups <folder>)Backup now and Restore a backup work
with --token <secret>a box that asks for the token once
on a data folder with usersa Log in form

HTTP: The console page is there (HEAD: only the headers)

HEAD /

Response:

HTTP 200 (text/html)

The screen

+-------------------------------------------------------------------------------------------+
| KDB [Home v]  Database [market v] New database   boss (admin) Log out  * Connected  Help   |
+-----------------------+----------------------------------------------------------+--------+
| OBJECTS       Refresh | [Run Ctrl+Enter] [Run all Ctrl+Shift+Enter] [History]  Rows | Monitor|
| [Tables 6][Views][Trig]|  1  SELECT time, open, high, low, close, volume          | Health |
| [Procs][Funcs][Timers] |  2  FROM ochl_day WHERE symbol = 'CITY';                | Samples|
|  > brokers     REL    |========================= (drag) ============================| Databa.|
|  > ochl_day    TS     | [1 SELECT time, ...] [2 Error]                           | ------ |
|  ...                  | [Grid][Chart]  message                      [Export CSV] | Tools  |
|                       |                                                          |Terminal|
|  > Indexes            |  #  time                      open   high ...            |        |
|                       |========================= (drag) ============================|        |
|                       | TERMINAL [All][Queries][Writes][Timers][Errors]  Pause Clear x|        |
|                       | 14:19:02.114 PG  10.0.0.5  market  3 ms  1 row  SELECT ...    |        |
+-----------------------+----------------------------------------------------------+--------+
| 19 rows | parse 0.05 ms  execute 0.34 ms  round trip 12 ms           Server 2026-09-11 14:19 |
+-------------------------------------------------------------------------------------------+
PartWhat it is
Top barthe Home menu, the database picker, New database, folder and version, the logged-in user and Log out, the connection state, Help, the theme button
Left sideone tab each for Tables, Views, Triggers, Procedures, Functions and Timers
Editorwhere you write SQL, with the Run, Run all, History buttons and the Rows limit
Resultsone tab per statement; each result as a Grid or a Chart; Export CSV
Terminala live log of what the server does (terminal); shown and hidden with the Terminal button
Right sidebuttons that open the Monitor, Health, Samples, Databases and Tools panels
Status barrows, times, and the server's clock

The lines between the editor, the results and the terminal can be dragged; the console remembers the sizes.

Editor

Write SQL here. Keywords, text and numbers get colors, and lines have numbers.

Button or keyWhat it does
Run or Ctrl+EnterRuns the statement under the cursor. When text is selected, runs only the selection.
Run all or Ctrl+Shift+EnterRuns everything in the editor
RowsThe most rows each statement gives back: 1,000, 10,000 (default), 100,000 or 1,000,000
TabPuts in two spaces

The console runs each statement with POST /exec?compat=0&limit=<Rows>.

History

History lists the last 50 statements you ran, newest first, with the time. Click one to put it back at the end of the editor.

Results grid

The grid shows the rows of one result.

ActionWhat it does
Click a column headerSort: small to big, then big to small, then back to the first order (sorting uses the rows already loaded)
Drag the right edge of a headerChange the column width
Click a cellSelect it
Ctrl+C, or double-click a cellCopy its value
Hover over long textSee all of it

Chart

Click Chart above a result. The console looks at the columns and picks the chart that fits best: candles for time, open, high, low, close (with volume bars when there is a volume column), a line for a time column with numbers, a bar chart for a text column with numbers, and so on. The button is off when no chart fits (a chart needs at least one number column).

The bar above the chart:

ControlWhat it does
Chart type listChoose another chart. Types that do not fit the columns are greyed out and say what they need.
ColumnsChoose which column is the time or category, the values, the series (one line per value of a text column), and "One chart per"
Symbol listWhen a text column has several values (many symbols), the chart shows one of them; pick it here
Indicators(time charts) Add SMA, EMA, Bollinger bands, RSI, MACD or stochastic, and set their periods
LogA logarithmic value scale (values must be above 0)
No gaps(time charts) Leave out time without rows (nights, weekends, holidays), so every row has the same width
LegendClick a name to hide or show that series
Reset, PNG, CSV, Full screenReset the zoom; save the chart as a picture; save the chart's rows as a CSV file (from the browser, no new query); fill the whole screen
Add to dashboardPut this statement and this chart on a dashboard as a new panel

Chart types:

GroupTypes
PriceCandlestick, OHLC bars
TimeLine, Step line, Area, Stacked area
CompareBar (vertical), Bar (horizontal), Grouped bar, Stacked bar
SpreadHistogram, Box plot, Scatter, Bubble
SharePie, Donut, Treemap
HeatmapCalendar heatmap, Matrix heatmap
NumberKPI number, Gauge
TableA table with green/red change columns, color scales and a sparkline (a small price line) per row
Mouse or key (on the chart)What it does
Mouse wheel, or + and -Zoom in and out
Drag, or Shift + arrow keysMove
Double-click, Home or 0Reset the zoom
Move the mouse, or arrow keysA crosshair and a tooltip with the values of that row
Two fingers (touch screen)Pinch to zoom
FFull screen; Esc leaves it

Example: A good query for candles (sample data: sample)

SELECT time, open, high, low, close, volume
FROM ochl_day
WHERE symbol = 'CITY'
ORDER BY time;

Result:

time (TIMESTAMP)open (DOUBLE)high (DOUBLE)low (DOUBLE)close (DOUBLE)volume (DOUBLE)
2025-12-28T00:00:00.000Z540.3542.5539.2542.285290
2025-12-29T00:00:00.000Z540.6542.1538.8539.752010
2025-12-30T00:00:00.000Z538.5540.5536.4539.395460
2025-12-31T00:00:00.000Z540.4546.2538.9542.422330
2026-08-23T00:00:00.000Z505508.4502507.9125050

(first 5 of 19 rows)

Charts and dashboards

A chart you like can go on a dashboard: a page of several charts, each from its own query, that refresh by themselves. Click Add to dashboard on the chart bar, pick a dashboard (or A new dashboard) and give the panel a title. The dashboard opens with the new panel; click Save there to keep it. The dashboard page is explained in dashboards.

Example: Rows for a bar chart: shares traded per symbol (sample data: sample)

SELECT symbol, sum(quantity) AS shares
FROM trade_log
GROUP BY symbol
ORDER BY shares DESC;

Result:

symbol (SYMBOL)shares (LONG)
COAST3070
TELCO2770
CITY2420
VOLT400

(4 rows)

Export CSV

Export CSV downloads all rows of the shown result as a CSV file.

Object list

The left side lists the objects of the chosen database, one tab for each kind: Tables, Views, Triggers, Procedures, Functions and Timers. Each tab shows how many there are. The console remembers the tab you picked.

Folders. A database with many objects can be tidied into folders: + Folder at the top of a tab makes one, and you drag a table, view, trigger, procedure or function onto it. A folder exists in every tab, so floorsheet can hold the floor-sheet tables in the Tables tab and the floor-sheet procedures in the Procedures tab. Hover a folder's heading to rename (✎) or remove (×) it; removing a folder only puts its objects back in the plain list. Folders change nothing but this list: no name, statement or query is affected. They are saved in the table _console_groups of the database, so every browser sees the same folders; the first folder creates that table, which needs the admin role, and dragging needs the write role.

Tables

MarkMeaning
TS badgea time-series table (with its partition: DAY, MONTH, YEAR)
REL badgea relational table
TS on a columnthe table's time column
PKprimary key
FKREFERENCES another table (hover to see which)
FXa computed column
ActionWhat it does
Click the small arrowShow the columns and their types
Click a table or column namePut the name into the editor at the cursor
Double-click a table nameRun SHOW COLUMNS FROM <table>
RefreshReload the object lists and the health panel

The list comes from GET /api/info. It also reloads every 30 seconds while the page is visible.

Timers

A timer runs SQL by itself on a schedule, for example CALL refresh_prices(); every 5 minutes, so a table stays up to date without anybody running anything. The server runs it, so it goes on when no browser is open. Full details: timers.

In the Timers tabWhat it does
New timerA form: name, schedule, the SQL, and whether it is turned on. Run picks a procedure or function of this database.
Keep data for...Pick time-series tables and how long they keep their rows. It sets a TTL, or makes a monthly timer that drops old partitions. The Keep data page does the same for one table at a time.
ReloadReads the list again (it also refreshes by itself while the tab is open)
The dot before a namegreen: the last run worked; red: it failed; blue: running now; dashed: turned off
Click the arrowNext run, last run, how long it took, rows, the error, and how many runs
Run nowRuns it once now, whatever the schedule says
Turn off / Turn onStops or starts running it on the schedule
Edit, DeleteChange the schedule or the SQL; delete the timer (the procedure stays)

Schedules: every 30s, every 5m, every 2h, hourly, hourly :15, daily 16:00, daily 02:00,13:30, weekdays 11:00, monthly 1 02:00. The form offers the common ones as quick picks. Times are the server computer's local time.

Right side: Monitor, Health, Samples, Databases

The buttons down the right side open a panel over the page. The same button closes it again; so do the x and Esc.

ButtonThe panel
Monitormemory, processor, caches and the statements running now (Monitor)
Healthdamaged files, backups, Check now and Backup now (health); the button gets a red dot while a file is damaged
Samplesready statements with Insert and Run
Databasesevery database with its tables, size, folder and old log (wal_archive: its limit, whether it is its own or the server default, and the size on disk); click one to use it; New database; Old log sets a database's own limit, Off, or the server default again (SET WAL_ARCHIVE); Delete
ToolsPurge trash frees disk space in the whole data folder (PURGE TRASH ALL); Delete all data empties every table of the chosen database after you type its name (TRUNCATE ALL TABLES)
Terminalnot a panel: shows or hides the terminal at the bottom of Home

Terminal

The terminal at the bottom of Home is a live log of what the server does: every statement, write, timer run, login and backup, as it happens. It shows where the data comes from, for example a program on the PostgreSQL port or a timer.

14:19:02.114  PG     10.0.0.5 app    market   3 ms       1 row  SELECT price FROM ochl_day WHERE ...
14:19:02.530  HTTP   10.0.0.9        market  12 ms  12,000 rows  12,000 rows into trade_log (line protocol)
14:20:00.004  TIMER  refresh_prices  market  41 ms    350 rows  CALL refresh_prices();
Column or controlWhat it is
Timewhen it finished, with milliseconds, in your computer's time zone
SourceHTTP (statements, /write and CSV imports), PG (PostgreSQL port), TIMER, BACKUP (a scheduled backup), DEFERRED (a job of a deferred trigger), or the kind, such as LOGIN
Fromthe address of the program, and the user
Database, time, rowswhere it ran, how long it took, how many rows
All, Queries, Writes, Timers, Errorsshow only that kind of line
This databaseonly lines of the database chosen at the top
Filter textonly lines with that text
Pause, Clear, xstop adding lines, empty the list, hide the terminal

Health panel

LineMeaning
OK - no damaged files (green) or DAMAGED (n) (red)files KDB knows are damaged, with their names
Last backuphow long ago (just now, 3 h ago), never, or no backup folder; (copy failed) when the copy command failed. Hover it for the folder, the schedule and the last copy.
Datasize and number of the data files
Log LSNthe number of the last change in the log; it grows with every change
Openedwhen the server opened the database
Recovery at openwhat KDB did when it opened the database (it opens by itself when something was wrong)
Check nowreads every block of every file and the log (POST /api/check). Example message: OK: 11 files (76.1 KB) and 1 log segments read in 1.50 ms. No damage.
Backup nowmakes a verified backup (POST /api/backup). Example message: Backup 20260911-083519-806 created and verified: 9 files, 222.3 KB. The button is off when backups are off (--backups off).
Restore a backupopens a small form: the backups of this database, how far back a restore up to a time can go (the window), a time (empty = the backup as it was) and a new name. Restore makes the new database while this one keeps running (POST /api/restore). Then Swap ... in gives this database the restored data and the new one the old data (swap); it asks first.

If Check now finds damage: stop the server and run kdb repair (backup and safety).

Database picker and New database

Login form and token box

Users. When the data folder has users, the console shows Log in. Type the user name and password.

Token. On a server started with --token, the console shows Access token required. Type the token once.

The connection state at the top says Connected, Offline (the server does not answer), Token required or Login required. More: logins and tokens.

Theme

The button at the top right switches between the dark theme (the default) and the light theme. The browser remembers the choice. The help panel and charts follow the theme.

Help menu

The Help button in the top bar opens a menu:

ItemWhat it does
DocumentationOpens this help in a panel on the right side of the console. Drag its left edge to make it wider; Open in new tab shows it as a full page; Close or Esc closes it.
Help for word under cursor (F1)Opens the help for the keyword or function at the cursor in the editor: on round( it opens the function round, on ORDER in ORDER BY it opens ORDER BY. Inside a text '...' or a -- comment, it opens the help's start page.
Examples...A list of the ready examples of this help, with a search box and a preview. Insert into editor puts the chosen example (with the tables it needs) at the end of the editor; then press Ctrl+Enter. Open in help shows it in the help.
Keyboard shortcutsThe table below
Comments and suggestionsA form to send a comment, a problem or an idea to whoever runs this server. An admin also sees the messages sent so far and marks them read or done (feedback).
About KDBThe version, the database and its folder, the data folder, number of tables, the backup folder, how you are logged in, the help's version, and the server address

Keyboard shortcuts

KeysWhat it does
Ctrl+EnterRun the statement under the cursor (or the selected text)
Ctrl+Shift+EnterRun every statement in the editor
TabPut two spaces in the editor
F1Help for the keyword or function under the cursor
Ctrl+C (in the grid)Copy the selected cell
Double-click a cellCopy that cell
EscClose a menu, the History list, a dialog or the help panel
/ (in the help)Jump to the help's search box

On a Mac, use Cmd instead of Ctrl.

Syntax:

http://127.0.0.1:9900/#sql=<URL-encoded SQL>

A link of this form opens the console and puts the SQL at the end of the editor, selected, ready for Ctrl+Enter. It does not run the SQL by itself.

http://127.0.0.1:9900/#sql=SELECT%20symbol%2C%20close%20FROM%20ochl_day%20WHERE%20symbol%20%3D%20%27CITY%27%20LIMIT%205
$sql = "SELECT symbol, close FROM ochl_day WHERE symbol = 'CITY' LIMIT 5"
Start-Process ("http://127.0.0.1:9900/#sql=" + [uri]::EscapeDataString($sql))
import urllib.parse, webbrowser
sql = "SELECT symbol, close FROM ochl_day WHERE symbol = 'CITY' LIMIT 5"
webbrowser.open("http://127.0.0.1:9900/#sql=" + urllib.parse.quote(sql, safe=""))